.net中StopWatch的计算时间频率的问题!

今天为了测试算法性能,在C++下实现了一个类似.net StopWatch类的一个类。

为了看.net是怎么做的,就把.net的StopWatch 类的源码反编译出来看了下。

 

虽然最后我成功实现了C++的StopWatch,但是不看则已,看了之后更加迷惑了。

 

.net StopWatch类的实现原理如下:

 

1。判断你系统是否支持高性能计数器

采用的API如下:

QueryPerformanceFrequency()

QueryPerformanceCounter()

也就是说,优先采用这个方法,这是高分辨率性能计数器,是硬件层实现的。

我的计算机上执行出来,计时频率是:357,9545,也就是每秒大约357万次。换句话说计时精度大约是357万分之一秒。

 也就是用这种方法获得的一个tick表示大约279毫微秒(在我的机器上,不同机器这个值不同)(1 秒=10的9次方也就是10亿 毫微秒nanosecond).

但是奇怪的事情发生了。

2。如果你的计算机上不支持高性能计数器

微软采用的方法是:GetSystemTimeAsFileTime()

根据他的计算方法可以反推出,这个计时频率居然是:1000,0000,也就是1千万!精度可以到千万分之一秒!!!

查看MSDN文档可知,这个函数获得一个tick表示100毫微秒,在我的机器上,比高分辨率计数器分辨率要高2.7倍。

我的老天。

虽然绝大部分计算机都支持高性能计数器。也就是用这个类的时候第二种可能基本不会发生。

但是结果还是让我迷惑!

 

既然GetSystemTimeAsFileTime精度能到千万分之一秒,还要高分辨率高性能计数器干什么呢?

 

难道是因为前者计数性能很高,精度本来就会低些?

 

我采用两种方法都进行了实现,但是发现测试结果让人迷惑。也就是说测试结果证明高分辨率计数器显然确实分辨率更高。

难怪微软要优先采用高分辨计数器。

我一个耗时0.022ms(毫秒)的程序,采用GetSystemTime计算时间是显示0的,也就是说tick根本没有增加。

 

 

 

但是为啥MSDN说:SystemTime获得的tick表示100毫微秒。

 

结论总结:

   1。高分辨率的计时精度确实高于GetSystemTimeAsFileTime方法的精度。

   2。为什么MSDN说GetSystemTimeAsFileTime一个tick表示100毫微秒呢?说明这只是微软的规定,也就是说一个tick表示100毫微秒,但是并没有说我每隔100毫微秒就会加一个tick,也就是说tick在这儿只是微软的单位,实际计数的时候,不可能100毫微秒加1,而是按照某种分辨率(这个分辨率肯定比高分辨率低,我的机器上测试只有15.625ms),每次加N个tick,这个间隔时间除于tick的个数,正好等于100毫微秒而已!

附录:我的stopwatch类

/**************************************** filename:StopWatch.h *****************************************/ #pragma once #include<Windows.h> ///本类采用高分辨率高性能计数器实现 ///在我的Intel T7500机器上,分辨率大约是279毫微秒 class StopWatch { public: StopWatch(void); ~StopWatch(void); private: LARGE_INTEGER beginticks; LARGE_INTEGER endticks ; LARGE_INTEGER frequency;//高性能计数器的频率:每秒357,9545个tick 我的INTEL T7500 public: void Start(); void Stop(); double GetCostMillisecond(); unsigned long long GetFrequency(); }; /**************************************** filename:StopWatch.cpp *****************************************/ #include "StdAfx.h" #include "StopWatch.h" #include <Windows.h> #include<iostream> using namespace std; StopWatch::StopWatch(void) { beginticks.QuadPart=0; endticks.QuadPart=0; frequency.QuadPart=0; QueryPerformanceFrequency(&frequency); } StopWatch::~StopWatch(void) { } void StopWatch::Start() { //beginticks=GetTickCount(); QueryPerformanceCounter(&beginticks); } void StopWatch::Stop() { QueryPerformanceCounter(&endticks); } double StopWatch::GetCostMillisecond() { unsigned long long cost=(unsigned long long)(endticks.QuadPart-beginticks.QuadPart); double millsecond=(double)cost*1000.0/(double)frequency.QuadPart; return millsecond; } unsigned long long StopWatch::GetFrequency() { return (unsigned long long)frequency.QuadPart; } 

 

你可能感兴趣的:(.net,算法,测试,Integer,Class,微软)