本文对Windows及Linux平台下常用的计时函数进行总结,包括精度为秒、毫秒、微秒三种精度的各种函数。
比如Window平台下特有的Windows API函数GetTickCount()、timeGetTime()、及QueryPerformanceCounter(),
Linux平台下特有的gettimeofday()函数,以及标准的C/C++函数time()和clock()。下面分别对此进行简单介绍并附上示例代码。
通用的C/C++计时函数time()和clock()
time_t time(time_t *timer);
返回以格林尼治时间(GMT)为标准,从1970年1月1日00:00:00到现在的此时此刻所经过的秒数。
time_t实际是个long长整型typedef long time_t;
clock_t clock(void);
返回进程启动到调用函数时所经过的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock),以毫秒为单位。
clock_t实际是个long长整型typedef long clock_t;
Window平台特有函数
DWORD timeGetTime(void);
返回系统时间,以毫秒为单位。系统时间是从系统启动到调用函数时所经过的毫秒数。注意,这个值是32位的,会在0到2^32之间循环,约49.71天。
DWORD WINAPI GetTickCount(void);
这个函数和timeGetTime()一样也是返回系统时间,以毫秒为单位。
高精度计时,以微秒为单位(1毫秒=1000微秒)。
BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);得到高精度计时器的值(如果存在这样的计时器)。
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);返回硬件支持的高精度计数器的频率(次每秒),返回0表示失败。
其中LARGE_INTEGER其实是一个联合体,可以得到__int64 QuadPart;也可以分别得到低32位DWORD LowPart和高32位的值LONG HighPart。
在使用时,先使用QueryPerformanceFrequency()得到计数器的频率,再计算二次调用QueryPerformanceCounter()所得的计时器值之差,
用差去除以频率就得到精确的计时了。
Linux平台特有函数
int gettimeofday(struct timeval *tv,struct timezone *tz);
获得当前精确时间(1970年1月1日到现在的时间),精度为微秒。
保存时间的结构体
strut timeval {
long tv_sec; //秒数
long tv_usec; //微秒数
};
附上代码
1 #include <iostream> 2 3 #if defined(_WIN32) || defined(WIN32) /**Windows*/ 4 #define WINDOWS_IMPL 5 #include <windows.h> 6 #include <time.h> //time() 、 clock() 7 #include <Mmsystem.h> //timeGetTime() 8 #pragma comment(lib, "Winmm.lib") //timeGetTime() 9 #elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(BSD) /**Linux*/ 10 #define LINUX_IMPL 11 #include <sys/time.h> //gettimeofday() 12 #endif 13 #include <stdio.h> 14 15 /*********************************************************** 16 通用的: 17 time_t time(time_t *tloc); //返回从1970年1月1日0点以来的秒数,精度为秒 18 clock_t clock(): 返回该程序从启动到函数调用占用CPU的时间,精度为毫秒,但一般最小精度是33ms 19 20 Windows特有: 21 GetTickCount(): 返回从操作系统启动到现在所经过的毫秒数,精度毫秒,但最小精度是18ms 22 返回值以32位的双字类型DWORD存储,因此可以存储的最大值是2^32 ms约为49.71天, 23 timeGetTime(): 返回以毫秒计的系统时间,该时间为从系统开启算起所经过的时间,精度为毫秒 24 QueryPerformanceCounter(): 返回高精确度性能计数器的值,精度为微妙,但是确切的精确计时的最小单位是与系统有关的 25 26 Linux特有: 27 gettimeofday(struct timeval *tv,struct timezone *tz); 获得当前精确时间(1970年1月1日到现在的时间),精度为微秒 28 ***********************************************************/ 29 30 void MySleep(int sec_time) 31 { 32 #if defined(WINDOWS_IMPL) 33 Sleep(sec_time*1000); 34 #elif defined(LINUX_IMPL) 35 sleep(sec_time); 36 #endif 37 } 38 39 void test_time() 40 { 41 //通用的 42 //用time()来计时 秒 43 time_t timeBegin, timeEnd; 44 timeBegin = time(NULL); 45 MySleep(1); 46 timeEnd = time(NULL); 47 printf("%d\n", timeEnd - timeBegin); 48 49 /* 50 * Structure used in select() call, taken from the BSD file sys/time.h. 51 */ 52 //struct timeval { 53 // long tv_sec; /* seconds */ 54 // long tv_usec; /* and microseconds */ 55 //}; 56 timeval val; 57 58 //用clock()来计时 毫秒 59 clock_t clockBegin, clockEnd; 60 clockBegin = clock(); 61 MySleep(1); 62 clockEnd = clock(); 63 printf("%d\n", clockEnd - clockBegin); 64 65 #ifdef WINDOWS_IMPL 66 //Windows 67 68 //用GetTickCount()来计时 毫秒 69 DWORD dwGTCBegin, dwGTCEnd; 70 dwGTCBegin = GetTickCount(); 71 Sleep(1000); 72 dwGTCEnd = GetTickCount(); 73 printf("%d\n", dwGTCEnd - dwGTCBegin); 74 75 //用timeGetTime()来计时 毫秒 76 DWORD dwBegin, dwEnd; 77 dwBegin = timeGetTime(); 78 Sleep(1000); 79 dwEnd = timeGetTime(); 80 printf("%d\n", dwEnd - dwBegin); 81 82 //用QueryPerformanceCounter()来计时 微秒 83 LARGE_INTEGER large_interger; 84 double dff; 85 __int64 c1, c2; 86 QueryPerformanceFrequency(&large_interger); 87 dff = large_interger.QuadPart; 88 QueryPerformanceCounter(&large_interger); 89 c1 = large_interger.QuadPart; 90 Sleep(1000); 91 QueryPerformanceCounter(&large_interger); 92 c2 = large_interger.QuadPart; 93 printf("高精度计时器频率%lf\n", dff); 94 printf("第一次计时器值%I64d 第二次计时器值%I64d 计时器差%I64d\n", c1, c2, c2 - c1); 95 printf("计时%lf毫秒\n", (c2 - c1) * 1000 / dff); 96 97 #elif defined(LINUX_IMPL) 98 //Linux 99 100 struct timeval tpstart,tpend; 101 double timeuse; 102 gettimeofday(&tpstart,NULL); 103 sleep(1); 104 gettimeofday(&tpend,NULL); 105 timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+tpend.tv_usec-tpstart.tv_usec;//注意,秒的读数和微秒的读数都应计算在内 106 printf("used time:%fus\n",timeuse); 107 #endif 108 109 } 110 111 int main() 112 { 113 test_time(); 114 getchar(); 115 return 0; 116 }
在Windows平台下运行结果如下:
在Linux平台下运行结果如下: