今天为了测试算法性能,在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类