The documentation about System.Diagnostics.Stopwatch class describes it as following: “[Stopwatch] provides a set of methods and properties that you can use to accurately measure elapsed time.”
I’ll be the first one to admit that I frequently took the DateTime.Now.Ticks shortcut when doing rough profiling just because I was too lazy to declare the QueryPerformanceFrequency and QueryPerformanceCounter APIs. Using Stopwatch class is as easy as DateNow.Now, and, if you, in fact, get more accurate resolution, that’d be a great tool to have in your arsenal…
So, how is the Stopwatch class implemented?
First, at the construction time it tries to get the frequency of the high-resolution performance counter provided by the OEM (QueryPerformanceFrequency API call). If the call fails, it assumes the default 10,000 ticks per millisecond.
When you invoke the Start method, and the Stopwatch was not running (i.e. you did not call Start method twice in a row without stopping it), then it gets the timestamp. Calling Start on a running Stopwatch is a NOP (no-op). If the QueryPerformanceFrequency call succeeded in the constructor, i.e. high resolution performance counter is supported by the hardware, then QueryPerformanceCounter is called; otherwise, it falls back to the DateTime.UtcNow.Ticks call.
StartNew method is a constructor + Start method invocation in one.
The Stop method, as you might expect, is a simple act of getting the timestamp (same way as during the Start method), and then calculate the elapsed time (endTimeStamp – startTimeStamp + previouslyRecordedElapsedTime). Of course, the Stop is a NOP if the stopwatch is not running.
The Reset method, in essence, stops the stopwatch if it’s running, and resets previouslyRecordedElapsedTime to zero.
The other properties like ElapsedTicks, ElapsedMilliseconds, Elapsed, are just conversions of the elapsed time into ticks, milliseconds and TimeSpan accordingly.
As you can see, it’s a simple, but a very useful class…