Why are DateTime.Now and StopWatch drifting?

I made a small test application in C # that sets DateTime.Now and starts StopWatch . Every ten seconds I print _stopwatch.Elapsed.TotalMilliseconds and (DateTime.Now - _startTime).TotalMilliseconds .

Until I expect both to be the same, I was surprised to see that they diverged linearly by about one millisecond in 20 seconds. I assume DateTime.Now calls the system clock, and StopWatch do some accumulation?

Output Example:

 StopWatch : 0,2 DateTime : 1,0 Diff : 0,81 StopWatch : 10000,5 DateTime : 10002,6 Diff : 2,04 (...) StopWatch : 2231807,5 DateTime : 2231947,7 Diff : 140,13 StopWatch : 2241809,5 DateTime : 2241950,2 Diff : 140,70 

Full source: https://gist.github.com/knatten/86529563122a342de6bb

Exit: https://gist.github.com/knatten/84f9be9019ee63119ee2

+8
c #
source share
3 answers

The answer is relatively direct.

  • A stopwatch counts processor ticks using a performance counter, a mechanism that varies between processors.
  • DateTime requests a system clock - the system clock is periodically updated by windows using the output data (possibly quartz) of the crystal clock on your motherboard.

All clock drifts and these two different synchronization mechanisms will drift at different speeds.

Under the hood, Stopwatch uses this API.

The stopwatch class helps manipulate timing related performance counters in managed code. In particular, the frequency field and the GetTimestamp method can be used instead of the unmanaged Win32 API QueryPerformanceFrequency and QueryPerformanceCounter.

DateTime uses this API

+3
source share

DateTime.Now ticking every few milliseconds. In addition, the speed at which it is ticking is not fixed from car to car. On modern Windows systems, you can expect a tick resolution of around 100 ticks per second.

StopWatch , StopWatch other hand, requests processor hardware for high accuracy. In fact, you can get StopWatch permission with Stopwatch.Frequency .

I did not know both of the above until I read Eric Lippert's interesting post on errors related to common performance errors, see here . This is a really great post.

+3
source share

Stopwatch much more accurate than DateTime , which explains the mismatch

From MSDN :

The stopwatch measures elapsed time by counting the timer marks in the basic timer mechanism. If the installed hardware and operating system supports a high-resolution performance counter, the stopwatch class uses this counter to measure elapsed time. Otherwise, the stopwatch class uses a system timer to measure elapsed time. Use the Frequency and IsHighResolution fields to determine the accuracy and resolution of the stopwatch timing implementation.

+2
source share

All Articles