我在WinForm中有以下代码:
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
Dim startTime = DateTime.Now
MyBase.OnMouseMove(e)
Dim result As Double = 45654654
For i = -1000 To 1000
result = result / i
Next i
Dim endTime = DateTime.Now
Console.WriteLine(">>> OnMouseMove time = {0}(ms) (start={1}:{3}; end={2}:{4})", (endTime - startTime).TotalMilliseconds, startTime.ToLongTimeString(), endTime.ToLongTimeString(), startTime.Ticks, endTime.Ticks)
End Sub
这是不可思议的,但似乎需要任何毫秒的操作...... ANY TICK !!!
结果是
>>> OnMouseMove time = 0(ms) (start=15:56:03:634432317630699089; end=15:56:03:634432317630699089)
>>> OnMouseMove time = 0(ms) (start=15:56:03:634432317630855340; end=15:56:03:634432317630855340)
>>> OnMouseMove time = 0(ms) (start=15:56:03:634432317630855340; end=15:56:03:634432317630855340)
>>> OnMouseMove time = 0(ms) (start=15:56:03:634432317631011591; end=15:56:03:634432317631011591)
>>> OnMouseMove time = 0(ms) (start=15:56:03:634432317631011591; end=15:56:03:634432317631011591)
>>> OnMouseMove time = 0(ms) (start=15:56:03:634432317631167842; end=15:56:03:634432317631167842)
我有什么问题吗?
在另一个版本中,我试着睡100个小时
Next i
' sleep 100 ms '
System.Threading.Thread.Sleep(100)
Dim endTime = DateTime.Now
,但这里有惊喜,而不是100我凝胶总是93,7506或109,3757:
>>> OnMouseMove time = 93,7506(ms) (start=16:05:26:634432323267766416; end=16:05:26:634432323268703922)
>>> OnMouseMove time = 93,7506(ms) (start=16:05:26:634432323268860173; end=16:05:26:634432323269797679)
>>> OnMouseMove time = 109,3757(ms) (start=16:05:26:634432323269797679; end=16:05:27:634432323270891436)
>>> OnMouseMove time = 93,7506(ms) (start=16:05:27:634432323270891436; end=16:05:27:634432323271828942)
>>> OnMouseMove time = 93,7506(ms) (start=16:05:27:634432323271828942; end=16:05:27:634432323272766448)
>>> OnMouseMove time = 109,3757(ms) (start=16:05:31:634432323315891724; end=16:05:31:634432323316985481)
答案 0 :(得分:4)
由于您不在循环外使用i
,因此可能会优化掉。因此,您需要对DateTime.Now
和减法进行两次调用。
此外,由于最近的CPU能够每秒发送数十亿次操作,因此只需几千次操作(从L1缓存和寄存器中获取的数据很少)将花费时间以*微秒为单位。
顺便说一句。如果你想做时间,Stopwatch
类型是一种更好的方法。
答案 1 :(得分:2)
DateTime.Now
没有高准确度。通常默认情况下大约为16ms,使用timeBeginPeriod
可以减少到1ms。请注意,timeBeginPeriod
具有系统范围的影响,可能会增加计算机的功耗。所以不应该轻易使用它。
想象一下,你在内核中有一个定时器,它每16ms运行一次某个函数。此函数更新DateTime.Now
使用的当前时间。然后它决定在接下来的16ms内运行哪个线程
如果你打电话给sleep(100)
,你的线程将不会在接下来的约100ms内运行。但Windows并没有立即注意到100毫秒已经启动。它只会注意到下一个计时器事件。然后它决定再次运行你的线程。
这与Windows中的计时器粒度有关,并影响许多windows api函数,例如GetTickCount
,Sleep
,线程调度和计时器间隔。
要衡量效果,请使用基于QueryPerformanceCounter
的StopWatch
类,并且不会遇到此问题。 (不幸的是,在某些多核计算机上,不同核心的时钟不同步,这是错误的。如果你的线程被安排在另一个核心上,当它以更大的间隔向后或向前跳跃时,不要感到惊讶)
答案 2 :(得分:2)
当您尝试衡量流程的耗用时间,尤其是短期运行流程时,您希望使用更好的工具System.Diagnostics.Stopwatch
。
DateTime.Now
在测量过程持续时间方面不具备精确度和准确度的适当组合。
有关详情,建议您查看Eric Lippert's blog entry。
答案 3 :(得分:2)
你必须使用秒表
正如其他人发布的那样
进一步..
你的循环:
Dim result As Double = 45654654
For i = -1000 To 1000
result = result / i
Next i
将被删除
如果你有,请使用JIT COMPILER优化因此无法使用
答案 4 :(得分:1)
尝试使用秒表,但考虑到现代计算机以纳秒计算,我可以看到它花费不到一毫秒来增加整数2000次。
答案 5 :(得分:1)
是。使用DateTime.Now来测量精确的时间并不准确。请改用Stopwatch。