[原创分享]关于1ms精密度的计时延时器的基本测试
[原创分享]关于1ms精度的计时延时器的基本测试
2013年11月30日补充:
之前写这篇文章时,因为已经使用win7一段较长的时间,所以没针对API帮助提到的Period方面的精度控制,在WinXP系统下做测试,后来找时间测试了下,不加timeBeginPeriod的话,那两个API在XP下精度远不到1ms。当初写这篇文章的主要目的,是闲聊一下自己测试代码执行速度的一些办法。现在打算结帖了,考虑到确实还有不少程序需要在winxp和win2003下使用,而且即使只在WIN7以上系统中运行,按官方的API说明,加上timeBeginPeriod的设置,也更严谨些,毕竟我也没看到哪里说,在WIN7下这个调用是可以省去的,搞不好在有些地方没调用timeBeginPeriod就不够精度呢。唉,不废话了,直接贴补充的代码。对了,有趣的是,加了timeBeginPeriod(1)后,在xp下多次测试那段DoTestSleep的代码,返回值都是2,不像win7下那样是1.
注意:这里说的1ms精度,只是指在适当条件(比如说CPU占用率不太高)下,用下述代码实测时,一般能达到的时间上的分辨率。就好像说一个人视力2.0,是指的他在准备充分条件下,去光线等条件符合相关标准的视力测试表前能测到2.0的水准,并不是说他在睡眼矇眬或长时间盯着电脑屏幕,或其它平时常见的生活状态下都能测试出有这个成绩。绝不能理解为“MS的windows系统能保证这些API实际执行时,所有情况都能有1ms的精度”。如果有“准确率”方面的严苛要求,建议多了解实时操作系统(RTOS)方面的知识。本人那方面了解不多,也就不多讨论了。
刚发了篇小博文,特别适合小白,考虑到论坛里很多人不怎么上博客,在这里也宣传一下
http://blog.****.net/bcrun/article/details/13772257
关于1ms精度的计时延时器的基本测试
一般来说,在平时编程中,出于优化代码运行速度等需求,常需要测算时间,这就需要对相关计时函数的精度做一番了解,不能老是糊里糊涂混日子。下面的测试由此而来
首先,我们需要测出,常用的计时函数中哪个达到了1ms精度。先测GetTickCount
如果只100000次的话,因为工作量太小,一般会输出0。不过不用担心,我们逐步加大循环次数,多测几次就行了。注意循环次数的跨度不要太大了,可以200000,300000这样的依次增加。这样你会发现,到了某一次,比如说500000,输出值会突然从0跳到16左右。可见这个API的实际精度只有约16ms.
写到这里时,可能已经有初学者急着要知道1ms精度的函数在哪了,别急,timeGetTime就是了:
测试代码几乎一样。测试结果为,在本人机器上,循环次数在100000时输出值就约为2-3了,次数增加1倍到200000的话,结果为4-5.如果减小到50000,则是1-2.可见,这个计时函数的精度为1ms.
接下来,因为确认了timeGetTime的精度可以达到1ms,我们可以放心测算延时函数sleep的实际精度了,先公布结果,1ms.
最后补充说明一下,获取UTC时间的GetSystemTime和相应的SystemTimeToFileTime,实际精度也是1ms
2013年11月30日补充:
之前写这篇文章时,因为已经使用win7一段较长的时间,所以没针对API帮助提到的Period方面的精度控制,在WinXP系统下做测试,后来找时间测试了下,不加timeBeginPeriod的话,那两个API在XP下精度远不到1ms。当初写这篇文章的主要目的,是闲聊一下自己测试代码执行速度的一些办法。现在打算结帖了,考虑到确实还有不少程序需要在winxp和win2003下使用,而且即使只在WIN7以上系统中运行,按官方的API说明,加上timeBeginPeriod的设置,也更严谨些,毕竟我也没看到哪里说,在WIN7下这个调用是可以省去的,搞不好在有些地方没调用timeBeginPeriod就不够精度呢。唉,不废话了,直接贴补充的代码。对了,有趣的是,加了timeBeginPeriod(1)后,在xp下多次测试那段DoTestSleep的代码,返回值都是2,不像win7下那样是1.
Public Declare Function timeBeginPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Public Declare Function timeEndPeriod Lib "winmm.dll" (ByVal uPeriod As Long) As Long
Private Sub Form_Initialize()
Call timeBeginPeriod(1)
End Sub
Private Sub Form_Terminate()
Call timeEndPeriod(1)
End Sub
注意:这里说的1ms精度,只是指在适当条件(比如说CPU占用率不太高)下,用下述代码实测时,一般能达到的时间上的分辨率。就好像说一个人视力2.0,是指的他在准备充分条件下,去光线等条件符合相关标准的视力测试表前能测到2.0的水准,并不是说他在睡眼矇眬或长时间盯着电脑屏幕,或其它平时常见的生活状态下都能测试出有这个成绩。绝不能理解为“MS的windows系统能保证这些API实际执行时,所有情况都能有1ms的精度”。如果有“准确率”方面的严苛要求,建议多了解实时操作系统(RTOS)方面的知识。本人那方面了解不多,也就不多讨论了。
刚发了篇小博文,特别适合小白,考虑到论坛里很多人不怎么上博客,在这里也宣传一下
http://blog.****.net/bcrun/article/details/13772257
关于1ms精度的计时延时器的基本测试
一般来说,在平时编程中,出于优化代码运行速度等需求,常需要测算时间,这就需要对相关计时函数的精度做一番了解,不能老是糊里糊涂混日子。下面的测试由此而来
首先,我们需要测出,常用的计时函数中哪个达到了1ms精度。先测GetTickCount
'声明:
Declare Function GetTickCount Lib "kernel32" Alias "GetTickCount" () As Long
'说明
用于获取自windows启动以来经历的时间长度(毫秒)
'返回值
Long,以毫秒为单位的windows运行时间
如果只100000次的话,因为工作量太小,一般会输出0。不过不用担心,我们逐步加大循环次数,多测几次就行了。注意循环次数的跨度不要太大了,可以200000,300000这样的依次增加。这样你会发现,到了某一次,比如说500000,输出值会突然从0跳到16左右。可见这个API的实际精度只有约16ms.
Private Sub DoTestGetTickCount()
Dim lTime1&, lTime2&
Dim i&
lTime1 = GetTickCount
For i = 1 To 400000
Next i
lTime2 = GetTickCount
Debug.Print lTime2 - lTime1
End Sub
写到这里时,可能已经有初学者急着要知道1ms精度的函数在哪了,别急,timeGetTime就是了:
Private Declare Function timeGetTime Lib "winmm.dll" () As Long
测试代码几乎一样。测试结果为,在本人机器上,循环次数在100000时输出值就约为2-3了,次数增加1倍到200000的话,结果为4-5.如果减小到50000,则是1-2.可见,这个计时函数的精度为1ms.
Private Sub DoTestTimeGetTime()
Dim lTime1&, lTime2&
Dim i&
lTime1 = timeGetTime
For i = 1 To 100000
Next i
lTime2 = timeGetTime
Debug.Print lTime2 - lTime1
End Sub
接下来,因为确认了timeGetTime的精度可以达到1ms,我们可以放心测算延时函数sleep的实际精度了,先公布结果,1ms.
Private Sub DoTestSleep()
Dim lTime1&, lTime2&
Dim i&
lTime1 = timeGetTime
Sleep 1 'delay 1 ms
lTime2 = timeGetTime
Debug.Print lTime2 - lTime1
End Sub
最后补充说明一下,获取UTC时间的GetSystemTime和相应的SystemTimeToFileTime,实际精度也是1ms
timeGetTime
sleep
- 1手把手教你VB.NET七层设计思路(1)
- 2怎么使用NET Reactor为您的.Net(C#VB.Net) 源代码加密
- 3vb.net中对exel用查询语句查询时,是否只识别 "select * from [Sheet1$]" 这一条语句啊
- 4vba示意颜色值的数据是什么类型?这种形式 &H000000FF&
- 5不同网段怎么连接SqlServer2000
- 6vb6.0 Do While Loop读取文件,本行不符合条件,跳出本次循环,进来下一行循环
- 7怎么用代码判断ACCESS数据库中A表中B字段的类型是否为long型,如果是,则改为double型
- 8怎么在程序代码中加载主窗体的ICO,在网上查了些资料,但没找到,麻烦大家了
- 9WORD VBA有关问题求教
- 10VB 新人flexgrid 下拉内容有关问题
- 上一篇:Counta()函数的使用解决办法
- 下一篇:怎么给微软的计算器穿上自己的马甲
文章评论
相关解决方案