【PE系列】之Windows平台下不同精度时间统计函数使用方法总结

时间:2021-06-08 08:44:15

DATE: 2019-3-5


前言

    前面讲述过Linux平台下时间统计函数的用法,见linux下时间有关的函数和结构体Linux下时间函数:struct timeval结构体。本文旨在讲述Windows平台下时间统计函数的使用方法以及跨平台统一时间函数SDK。

1、参考

windows下统计时间的函数
Windows 计算程序运行时间(高精度计时)
Windows 各种计算时间函数总结
Windows下获取当前时间函数汇总

2、Windows平台下时间统计函数使用方法
2.1、方法一:QueryPerformaceCounter()

头文件:#include <windows.h>

  如果需要更高的时间精度(比如说服务器程序的耗时统计),可以在开始计时统计前先调用QueryPerformanceFrequency()函数获得机器内部计时器的时钟频率,接着在需要严格计时的事件发生前和发生之后分别调用QueryPerformanceCounter(),利用两次获得的计数之差和时钟频率,就可以计算出事件经历的精确时间(精度可以达到微秒级别)。

用法如下:

#include <stdio.h>
#include <io.h>
#include <windows.h> //for GetTickCount function
#include <Mmsystem.h> //for timeGetTime function
#include <time.h> // for time function
#pragma comment(lib, "Winmm.lib") //for timeGetTime function


int main()
{
	int  N = 10000;
	double start_t,end_t,cost;
	LARGE_INTEGER begin;
	LARGE_INTEGER end;
	LARGE_INTEGER frequence;
	double duartion;

// method1:用timeGetTime()来计时,单位为ms
// DWORD dwBegin, dwEnd, dwBegin1, dwEnd1;
// dwBegin = timeGetTime();
// Sleep(N);
// dwEnd = timeGetTime();
// printf("timeGetTime Time: %d\n", dwEnd - dwBegin);

//method2:用GetTickCount()来计时,单位为ms
// dwBegin1 = GetTickCount();
// Sleep(N);
// dwEnd1 = GetTickCount();
// printf("GetTickCount Time: %d\n", dwEnd - dwBegin);
	
//method3:用time()来计时,单位为秒
// time_t begin,end;
// begin = time(NULL);
// Sleep(N);
// end = time(NULL);
// printf("time: %d\n", end - begin);

	
//method4:用clock()来计时,单位为ms
// start_t=clock(); 
// Sleep(10); 
// end_t=clock(); 
// cost=end_t-start_t; 
// printf("clock time: %d\n",cost); 

	QueryPerformanceFrequency(&frequence);

	QueryPerformanceCounter(&begin);
	Sleep(1234); 
	QueryPerformanceCounter(&end);
	duartion = (double)(end.QuadPart - begin.QuadPart) / (frequence.QuadPart);
	
	printf("QueryPerformaceCounter time: %1.3f s\n",duartion); //单位为秒,精度为微秒(1000000/cpu主频) 

	system("pause");
}

精度分析:精度较高,1微妙

2.2、方法二:clock()

头文件:#include <time.h>

clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t。在MSDN中,查得对clock函数定义如下:

clock_t clock(void) ;

简单而言,就是该程序从启动到函数调用占用CPU的时间。这个函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock);若挂钟时间不可取,则返回-1。其中clock_t是用来保存时间的数据类型。

用法如下:

#include <time.h> 
#include <stdio.h> 
int main()  
{  
    double start,end,cost;  
    start=clock();  
    sleep(1);  
    end=clock();  
    cost=end-start;  
    printf("%f\n",cost);  
    return 0;  
}

精度分析: 1ms

2.2、方法三:timeGetTime()

头文件:#include <Mmsystem.h>

引用库:#pragma comment(lib, “Winmm.lib”)

DWORD timeGetTime(VOID);    //毫秒为单位

作用: 返回从系统启动到调用函数时所经过的毫秒数。注意,这个值是32位的,会在0到2^32之间循环,约49.71天
用法如下:

#include <stdio.h>
#include <windows.h> 
#include <Mmsystem.h>
#pragma comment(lib, "Winmm.lib")

int main()
{
	int  N = 3;

	//用timeGetTime()来计时 毫秒
	DWORD  dwBegin, dwEnd;
	dwBegin = timeGetTime();
	Sleep(N);
	dwEnd = timeGetTime();
	printf("%d\n", dwEnd - dwBegin);

	system("pause");
}

精度分析:1ms

2.2、方法四:GetTickCount()

GetTickcount函数:它返回从操作系统启动到当前所经过的毫秒数,它的返回值是DWORD。常常用来判断某个方法执行的时间,其函数原型是

DWORD GetTickCount(void)

返回值以32位的双字类型DWORD存储,因此可以存储的最大值是(2^32-1) ms约为49.71天,因此若系统运行时间超过49.71天时,这个数就会归0,MSDN中也明确的提到了:“Retrieves the number of milliseconds that have elapsed since the system was started, up to 49.7 days.”。因此,如果是编写服务器端程序,此处一定要万分注意,避免引起意外的状况。

特别注意:这个函数并非实时发送,而是由系统每18ms发送一次,因此其最小精度为18ms。当需要有小于18ms的精度计算时,应使用StopWatch方法进行。

用法如下:

#include <stdio.h>
#include <windows.h> 
#include <Mmsystem.h>
#pragma comment(lib, "Winmm.lib")

int main()
{
	int  N = 5;

	//用timeGetTime()来计时 毫秒
	DWORD  dwBegin, dwEnd, dwBegin1, dwEnd1;
	dwBegin = timeGetTime();
	Sleep(N);
	dwEnd = timeGetTime();
	printf("timeGetTime: %d\n", dwEnd - dwBegin);

	dwBegin1 = GetTickCount();
	Sleep(N);
	dwEnd1 = GetTickCount();
	printf("GetTickCount: %d\n", dwEnd - dwBegin);

	system("pause");
} 

【PE系列】之Windows平台下不同精度时间统计函数使用方法总结
精度分析: 15~18ms

2.2、方法五:time()

头文件:#include <time.h>

time_t    time(time_t *timer);    // 秒为单位

返回以格林尼治时间(GMT)为标准,从1970年1月1日00:00:00到现在的此时此刻所经过的秒数。

time_t实际是个long长整型typedef long time_t;

用法如下:

#include <stdio.h>
#include <time.h> // for time function

int main()
{
	int  N = 10000;
//method3:用time()来计时,单位为秒
	time_t begin,end;
	begin = time(NULL);
	Sleep(N);
	end = time(NULL);
	printf("time: %d\n", end - begin);

	system("pause");
}

【PE系列】之Windows平台下不同精度时间统计函数使用方法总结
精度分析: 1s 精度最低

3、补充知识

UTC(世界标准时间),Calendar Time(日历时间),epoch(时间点),clock tick(时钟计时单元)
参考自:Windows下获取当前时间函数汇总

4、跨平台统一时间函数SDK

os_time.h

os_time.c


THE END!