I have the following code in a 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
This is incredible, but it seems that is take any millisecond that operations…
ANY TICK!!!
the result is
>>> 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)
Do I something wrong?
In an other varaint I try to sleep 100 ms
Next i
' sleep 100 ms '
System.Threading.Thread.Sleep(100)
Dim endTime = DateTime.Now
, but here surprise, innstead of 100 I gel always 93,7506 or 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)
DateTime.Nowdoesn’t have a high accuracy. Typically it’s around 16ms by default and get be reduced to 1ms usingtimeBeginPeriod. Note thattimeBeginPeriodhas system wide effects and can increase the power consumption of the computer. So it should not be used lightly.Imagine you have a timer in the kernel which runs a certain function every 16ms. This function updates the current time used by
DateTime.Now. Then it decides which thread to run for the next 16ms.If you call
sleep(100)your thread won’t run for the next about 100ms. But windows doesn’t instantly notice that the 100ms are up. It only notices on the next timer event. And then it decides to run your thread again.This is related to the timer granularity in windows and affects many windows api functions such as
GetTickCount,Sleep, thread scheduling and timer intervals.To measure performance use the
StopWatchclass which is based onQueryPerformanceCounterand doesn’t suffer from this problem. (Unfortunately it is buggy on some multicore machines where the clocks of different cores desync. Don’t be surprised if it jumps backward or forward in time for larger intervals when your thread gets scheduled on another core)