Higher-Order High-Resolution Timer for the Masses
Timing code is so common that many timers exist in the .Net Framework. One can resort to simplistic timing via
DateTime.Now, but this is a low-resolution timer that does not accurately reflect the current tick count and is therefore not usable for precision timing. As this MSDN article shows, its resolution is actually 10 ms for modern versions of Windows (NT 3.5 or later).
Also see this article about three timing tactics for .Net.
(System.Diagnostics.) Stopwatch to the rescue. This class is a simple stopwatch that is easy to use. However even this class can be repetitive to use many times. The way to make this even easier is to create a higher-order function. I wanted to create such a function but figured it would be nice to include in my extension method library on codeplex.
The problem is that dispatching off an action is not nice (not even the latest C# 4.0 mitigates this). So I created a new enum type Timer that reflects two units of measure – ticks and milliseconds. Now an extension method can dispatch over this type and measure time for a delegate. This is how the code is used (work is an Action that performs the work to be timed)
var ms = Timer.ms.Time(() => work());
If C# worked a little more like I’d like it to, it’d be possible to write something like this, using extension methods
var ms = Work.Time();
Maybe C# 5.0.
The latest improvement here, is a method to show (via
(System.Diagnostics.) Trace, which can be fed into the Console via a listener) the timing information in a nicely formatted way – it allows you to write this
Timer.µs.Show(() => Test(), "test"); Timer.Ticks.Show(() => Test(), "test");
The first line displays the measurements in whole microseconds, the seond one in the unit closest to the order of magnitude below or equal to one second. This eases formatting quite a bit. The output of a Ticks measurement looks like
test() finished in 235025 ticks (100 ms)
As you can see the appropriate unit (milliseconds) is chosen. This number is calculated based on Stopwatch.Frequency which defines the resolution of the underlying timer.
Notice the that the special character “µ”, which is a nice cherry on the top for this interface. I have also begun using the greek alpha, beta and gamma symbols for parametric type names to make them stand out more (although these symbols are also be useful for math variables, so it’s not a clear cut case on their usability for this purpose).
2009/10/10: updated the post with a correction and a couple of references: it is not Environment.TickCount that is (necessarily) imprecise (relatively speaking), it is DateTime.Now. However Stopwatch is the best approach to timing precisely since it exposes the timing frequency and whether the timer is actually high-precision as a boolean property (Environment does not appear to expose frequency information) and it is supposedly the highest-precision timer in the .Net Framework (BCL).
-  http://msdn.microsoft.com/en-us/library/system.datetime.now.aspx
-  http://reflexangle.blogspot.com/2009/04/datetimenow-vs-systemdiagnosticsstopwat.html
-  http://extensia.codeplex.com