本文目录
前言
前面讲述过Linux平台下时间统计函数的用法,见linux下时间有关的函数和结构体和Linux下时间函数:struct timeval结构体。
本文旨在梳理讲述Windows平台下时间统计函数的使用方法以及跨平台统一时间函数SDK。
1、参考
windows下统计时间的函数
Windows 计算程序运行时间(高精度计时)
Windows 各种计算时间函数总结
Windows下获取当前时间函数汇总
windows/linux 获取本地时间(精确到微妙)
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.3、方法三: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.4、方法四: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");
}
精度分析: 15~18ms
2.5、方法五: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");
}
精度分析: 1s 精度最低
3、补充知识
UTC(世界标准时间),Calendar Time(日历时间),epoch(时间点),clock tick(时钟计时单元)
参考自:Windows下获取当前时间函数汇总
4、跨平台统一时间函数SDK
说明:该SDK可用于Windows平台和Linux平台上的功能函数时间统计。
os_time_sdk.h
#ifndef _OS_TIME_SDK_H_
#define _OS_TIME_SDK_H_
#ifdef __cplusplus
extern "C"{
#endif
#if defined(WIN32) || defined(UNDER_CE) || defined(WIN64)
#include <windows.h>
#include <io.h>
typedef struct _os_timer
{
LARGE_INTEGER lpFrequency;
LARGE_INTEGER tStart;
LARGE_INTEGER tEnd;
}os_timer;
#elif defined(__GNUC__)
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
typedef struct _os_timer
{
struct timeval tStart;
struct timeval tEnd;
}os_timer;
#endif
int os_sdk_inittimer(os_timer *pTimer);
int os_sdk_starttimer(os_timer *pTimer);
int os_sdk_stoptimer(os_timer *pTimer);
int os_sdk_sleep(int msecs);
int is_file_exist(char *path);
#ifdef __cplusplus
};
#endif
#endif
os_time_sdk.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "os_time_sdk.h"
#if defined(WIN32) || defined(UNDER_CE) || defined(WIN64)
int os_sdk_inittimer(os_timer *pTimer)
{
QueryPerformanceFrequence(&pTimer->lpFrequency);
return 0;
}
int os_sdk_starttimer(os_timer *pTimer)
{
QueryPerformanceCounter(&pTimer->tStart);
return 0;
}
int os_sdk_stoptimer(os_timer *pTimer)
{
QueryPerformanceCounter(&pTimer->tEnd);
return (int)((pTimer->tEnd.QuadPart - pTimer->tStart.QuadPart)*1000/(pTimer->lpFrequency.QuadPart));
}
int os_sdk_sleep(int msecs)
{
Sleep(msecs);
return 0;
}
int is_file_exist(char *path)
{
return (_access(path, 0) == -1)? 0 : 1;
}
#elif defined(__GNUC__)
int os_sdk_inittimer(os_timer *pTimer)
{
return 0;
}
int os_sdk_starttimer(os_timer *pTimer)
{
gettimeofday(&pTimer->tStart, NULL);
return 0;
}
int os_sdk_stoptimer(os_timer *pTimer)
{
gettimeofdayy(&pTimer->tEnd, NULL);
return (pTimer->tEnd.tv_sec - pTimer->tStart.tv_sec)*1000 + (pTimer->tEnd.tv_usec - pTimer->tStart.tv_usec)/1000;
}
int os_sdk_sleep(int msecs)
{
usleep(msecs*1000);
return 0;
}
int is_file_exist(char *path)
{
return (access(path , 0) == -1) ? 0 : -1;
}
#endif
5、windows/linux 获取本地时间(精确到微妙)
参考自:windows/linux 获取本地时间(精确到微妙)
5.1、windows下获取本地时间的方法
#if defined(WIN32) || defined(UNDER_CE) || defined(WIN64)
#include<time.h>
#include<stdio.h>
#include<string.h>
#include<windows.h>
void getstimeval()
{
long time;
SYSTEMTIME sys;
unsigned int us;
LARGE_INTEGER tick;
LARGE_INTEGER timestamp;
QueryPerformanceFrequency(&tick);
QueryPerformanceCounter(timestamp);
us=(timestamp.QuadPart % tick.QuadPart)*1E6/tick.QuadPart;
GetLocalTime(&sys);
printf("%04d-%02d-%02d %02d:%02d:%02d.%06d\n",sys.wYear, sys.wMonth, sys.wDay, \
sys.wHour, sys.wMinute, sys.wSecond, us);
}
#endif
5.2、linux下获取本地时间的方法
#if defined(__GUNC__)
#include<sys/time.h>
#include<time.h>
#include<stdio.h>
#include<string.h>
void getstimeval()
{
char buf[28];
struct timeval tv;
struct tm tm;
size_t len = 28;
gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &tm);
strftime(buf, len, "%Y-%m-%d %H:%M:%S", &tm);
len = strlen(buf);
sprintf(buf + len, ".%06.6d", (int)(tv.tv_usec));
printf("%s\n",buf);
}
#endif
THE END!
本博文只能阅读,谢绝转载,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2963033731@qq.com