double t1 = (double)cv::getTickCount();//opencv
CQueryTime ct;//封装的QueryPerformanceCounter
DWORD start_gtickcount = GetTickCount();49天会溢出
time_t first = time(NULL);
clock_t start = clock();
COleDateTime tm1 = COleDateTime::GetCurrentTime();//计算两个时间的间隔大于68年时就会溢出
void PrintInfo()
{
TRACE("cv::getTickCount %f ms \r\n", (((double)cv::getTickCount() - t1) /getTickFrequency())*1000.0);
TRACE("CQueryTime %fms\r\n", (ct.Getlfms()));
TRACE("GetTickCount %fms \r\n", ((double)(GetTickCount() - start_gtickcount)));
TRACE("time_t %f ms\r\n", difftime(time(NULL), first)*1000.0);
TRACE("clock_t %fms \r\n", ((double)(clock() - start)));
COleDateTimeSpan sp = COleDateTime::GetCurrentTime() - tm1;
TRACE("COleDateTime COleDateTimeSpan %fs \r\n", sp.GetTotalSeconds());
}
cv::getTickCount 18505.399000ms
CQueryTime 18506.114100ms
GetTickCount 18500.000000ms
time_t 18000.000000ms
clock_t 18509.000000ms
COleDateTime COleDateTimeSpan 18.000000s
//修改计算机时间之后 日期倒退几分钟
cv::getTickCount 47415.887500ms
CQueryTime 47416.949000ms
GetTickCount 47407.000000ms
time_t -136000.000000ms
clock_t -1161495043.000000ms
COleDateTime COleDateTimeSpan -136.000000s
//这个类使用的是 QueryPerformanceFrequency QueryPerformanceCounter
class CQueryTime
{
public:
CQueryTime();
~CQueryTime();
void Init();
CString GetStrs();
double Getlfms();
private:
LARGE_INTEGER litmp_sum;
LONGLONG QPart1_sum;
LONGLONG QPart2_sum;
double dfMinus_sum;
double dfFreq_sum;
double dfTim_sum;
CString str_ConTime;
};
CQueryTime::CQueryTime()
{
Init();
}
CQueryTime::~CQueryTime(void)
{
}
void CQueryTime::Init()
{
dfMinus_sum = 0;
dfFreq_sum = 0;
dfTim_sum = 0;
str_ConTime = _T("");
dfMinus_sum = 0;
dfFreq_sum = 0;
dfTim_sum = 0;
str_ConTime = _T("");
//开始计时
QueryPerformanceFrequency(&litmp_sum);
// 获得计数器的时钟频率
dfFreq_sum = (double)litmp_sum.QuadPart;
QueryPerformanceCounter(&litmp_sum);
// 获得初始值
QPart1_sum = litmp_sum.QuadPart;
}
double CQueryTime::Getlfms()
{
//单位毫秒
//计时结束
QueryPerformanceCounter(&litmp_sum);
// 获得终止值
QPart2_sum = litmp_sum.QuadPart;
dfMinus_sum = (double)(QPart2_sum - QPart1_sum);
dfTim_sum = dfMinus_sum / dfFreq_sum * 1000.0;
return dfTim_sum;
}
/*用这个计算范围两个日期的时间差 返回天数*/
int GetDayDistance(int old_year,int oldmonth,int old_day,int new_year,int new_month,int new_day)
{
int nd(0), nm(0), ny(0);
int od(0), om(0), oy(0);
nm = (new_month + 9) % 12;
ny = new_year - (nm/10);
nd = (365*ny) + (ny/4) - (ny/100) + (ny/400) + ((nm*306 + 5)/10) + (new_day - 1);
om = (oldmonth + 9) % 12;
oy = old_year - (om/10);
od = (365*oy) + (oy/4) - (oy/100) + (oy/400) + ((om*306 + 5)/10) + (old_day - 1);
return nd - od;
}
以下内容来自:https://www.cnblogs.com/chmm/p/7461684.html
在我们调试代码的时候,很多时候需要用代码的运行时间来衡量代码的效率,看了网上已经有了很多关于计时的文章,自己学习的时候再进行一些整理吧。
1. time()函数
在头文件time.h中,time()获取当前的系统时间,只能精确到秒,返回的结果是一个time_t类型,其使用方法如下:
#include <time.h>
#include <stdio.h>
int main() {
time_t first, second;
first=time(NULL);
delay(2000);
second=time(NULL);
printf("The difference is: %f seconds",difftime(second,first)); //调用difftime求出时间差
return 0;
}
- clock()函数
在头文件time.h中,clock()函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock),常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元,精确到毫秒,其使用方法如下:
#include<time.h>
#include<stdio.h>
int main()
{
double dur;
clock_t start,end;
start = clock();
foo();//dosomething
end = clock();
dur = (double)(end - start);
printf("Use Time:%f\n",(dur/CLOCKS_PER_SEC));
}
3.timeGetTime()函数(Windows API)
以毫秒计的系统时间,该时间为从系统开启算起所经过的时间。在使用timeGetTime之前应先包含头文件#include <Mmsystem.h>或#include <Windows.h>并在project->settings->link->Object/library modules中添加winmm.lib。也可以在文件头部添加 #pragma comment( lib,“winmm.lib” )。
备注:命令行:#pragma comment( lib,“xxx.lib” )时预编译处理指令,让vc将winmm.lib添加到工程中去进行编译。
#include<stdio.h>
#include<windows.h>
#pragma comment( lib,"winmm.lib" )
int main()
{
DWORD t1, t2;
t1 = timeGetTime();
foo();//do something
t2 = timeGetTime();
printf("Use Time:%f\n", (t2 - t1)*1.0 / 1000);
return 0;
}
该函数的时间精度是五毫秒或更大一些,这取决于机器的性能。可用timeBeginPeriod和timeEndPeriod函数提高timeGetTime函数的精度。如果使用了,连续调用timeGetTime函数,一系列返回值的差异由timeBeginPeriod和timeEndPeriod决定。也可以用timeGetTime实现延时功能Delay
void Delay(DWORD delayTime)
{
DWORD delayTimeBegin;
DWORD delayTimeEnd;
delayTimeBegin=timeGetTime();
do
{
delayTimeEnd=timeGetTime();
}while((delayTimeEnd-delayTimeBegin)<delayTime)
}
4.QueryPerformanceCounter()函数和QueryPerformanceFrequency()函数(Windows API)
QueryPerformanceFrequency()函数返回高精确度性能计数器的值,它可以以微妙为单位计时,但是QueryPerformanceCounter()确切的精确计时的最小单位是与系统有关的,所以,必须要查询系统以得到QueryPerformanceCounter()返回的嘀哒声的频率。QueryPerformanceFrequency()提供了这个频率值,返回每秒嘀哒声的个数。
#include<stdio.h>
#include<windows.h>
#pragma comment( lib,"winmm.lib" )
int main()
{
LARGE_INTEGER t1, t2, tc;
QueryPerformanceFrequency(&tc);
QueryPerformanceCounter(&t1);
foo();//do something
QueryPerformanceCounter(&t2);
printf("Use Time:%f\n", (t2.QuadPart - t1.QuadPart)*1.0 / tc.QuadPart);
return 0;
}
5.GetTickCount()函数(Windows API)
GetTickCount返回(retrieve)从操作系统启动所经过(elapsed)的毫秒数,它的返回值是DWORD。
#include<stdio.h>
#include<windows.h>
#pragma comment( lib,"winmm.lib" )
int main()
{
DWORD t1, t2;
t1 = GetTickCount();
foo;//do something
t2 = GetTickCount();
printf("Use Time:%f\n", (t2 - t1)*1.0 / 1000);
return 0;
}
6.RDTSC指令(Windows)
在Intel Pentium以上级别的CPU中,有一个称为“时间戳(Time Stamp)”的部件,它以64位无符号整型数的格式,记录了自CPU上电以来所经过的时钟周期数。由于目前的CPU主频都非常高,因此这个部件可以达到纳秒级的计时精度。这个精确性是上述几种方法所无法比拟的.在Pentium以上的CPU中,提供了一条机器指令RDTSC(Read Time Stamp Counter)来读取这个时间戳的数字,并将其保存在EDX:EAX寄存器对中。由于EDX:EAX寄存器对恰好是Win32平台下C++语言保存函数返回值的寄存器,所以我们可以把这条指令看成是一个普通的函数调用,因为RDTSC不被C++的内嵌汇编器直接支持,所以我们要用_emit伪指令直接嵌入该指令的机器码形式0X0F、0X31。
inline unsigned __int64 GetCycleCount()
{
__asm
{
_emit 0x0F;
_emit 0x31;
}
}
void test6()
{
unsigned long t1,t2;
t1 = (unsigned long)GetCycleCount();
foo();//dosomething
t2 = (unsigned long)GetCycleCount();
printf("Use Time:%f\n",(t2 - t1)*1.0/FREQUENCY); //FREQUENCY指CPU的频率
}
获取CPU频率参考:http://blog.csdn.net/kofandlizi/article/details/6253801
7.gettimeofday() (Linux)
//timeval结构定义为:
struct timeval
{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
//timezone 结构定义为:
struct timezone
{
int tz_minuteswest; /*和Greenwich 时间差了多少分钟*/
int tz_dsttime; /*日光节约时间的状态*/
};
void test()
{
struct timeval t1,t2;
double timeuse;
gettimeofday(&t1,NULL);
foo();
gettimeofday(&t2,NULL);
timeuse = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec)/1000000.0;
printf("Use Time:%f\n",timeuse);
}
8.RDTSC指令计时(Linux)
#if defined (__i386__)
static __inline__ unsigned long long GetCycleCount(void)
{
unsigned long long int x;
__asm__ volatile("rdtsc":"=A"(x));
return x;
}
#elif defined (__x86_64__)
static __inline__ unsigned long long GetCycleCount(void)
{
unsigned hi,lo;
__asm__ volatile("rdtsc":"=a"(lo),"=d"(hi));
return ((unsigned long long)lo)|(((unsigned long long)hi)<<32);
}
#endif
void test8()
{
unsigned long t1,t2;
t1 = (unsigned long)GetCycleCount();
foo();//dosomething
t2 = (unsigned long)GetCycleCount();
printf("Use Time:%f\n",(t2 - t1)*1.0/FREQUENCY); //FREQUENCY CPU的频率
}
9.GetSystemTime / GetLocalTime(Windows)
Windows SDK 中有两个精确到毫秒的获取当前时间的函数:
GetSystemTime:获取 UTC 时间。
GetLocalTime:获取当地时间。
这两个函数的返回都是:SYSTEMTIME ,结构体占用了 16 个字节,它的定义如下:
typedef struct _SYSTEMTIME {
WORD wYear;
WORD wMonth;
WORD wDayOfWeek;
WORD wDay;
WORD wHour;
WORD wMinute;
WORD wSecond;
WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;
// GetSystemTime.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <Windows.h>
int _tmain(void)
{
SYSTEMTIME utc_time = { 0 };
SYSTEMTIME local_time = { 0 };
GetSystemTime(&utc_time);
GetLocalTime(&local_time);
_tprintf(_T("The UTC time is \t: %02d:%02d:%02d.%03d\n"), utc_time.wHour, utc_time.wMinute, utc_time.wSecond, utc_time.wMilliseconds);
_tprintf(_T("The local time is\t: %02d:%02d:%02d.%03d\n"), local_time.wHour, local_time.wMinute, local_time.wSecond, local_time.wMilliseconds);
return 0;
}
10.GetSystemTimeAsFileTime
究竟能不能达到 100 纳秒的精确度呢?在 Windows SDK 中有一个结构体:FILETIME,它可以记录精度达到 100ns 的时间。用哪个函数得到这个值呢?可以用 GetSystemTimeAsFileTime。但是,不要高兴得太早,虽
然 FILETIME 能够达到如此高的精度,但是这个函数我连试都懒得试。为什么呢?因为 Windows 系统并不是一个实时操作系统(Windows Embedded Compact 2013 是一个实时系统),其时钟精度一般认为是 15 ~ 16 毫秒。
Windows Sysinternals 给我们提供了一个查看你使用的 Windows 系统的时钟分辨率的小工具:ClockRes v2.0。把它下载下来在控制台中执行,结果如下:
这里写图片描述
看到了吧。死心了吧。所以说,用 GetSystemTime / GetLocalTime 就已经很好了。如果要获得真正毫秒级甚至更高精度的当前系统时间,必须跟 CPU 打交道,别无它法。先贴出代码吧:
#ifdef _WIN32
#include <windows.h>
#else
#include <time.h>
#endif // _WIND32
// 定义64位整形
#if defined(_WIN32) && !defined(CYGWIN)
typedef __int64 int64_t;
#else
typedef long long int64t;
#endif // _WIN32
// 获取系统的当前时间,单位微秒(us)
int64_t GetSysTimeMicros()
{
#ifdef _WIN32
// 从1601年1月1日0:0:0:000到1970年1月1日0:0:0:000的时间(单位100ns)
#define EPOCHFILETIME (116444736000000000UL)
FILETIME ft;
LARGE_INTEGER li;
int64_t tt = 0;
GetSystemTimeAsFileTime(&ft);
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
// 从1970年1月1日0:0:0:000到现在的微秒数(UTC时间)
tt = (li.QuadPart - EPOCHFILETIME) /10;
return tt;
#else
timeval tv;
gettimeofday(&tv, 0);
return (int64_t)tv.tv_sec * 1000000 + (int64_t)tv.tv_usec;
#endif // _WIN32
return 0;
}
参考资料:http://blog.csdn.net/luoweifu/article/details/51325432
http://blog.csdn.net/yapingxin/article/details/49466223
http://www.cnblogs.com/leven20061001/archive/2012/11/08/2760126.html
C++11的chrono库,可实现毫秒微秒级定时
https://blog.csdn.net/oncealong/article/details/28599655?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param