(originally posted at coreygoldberg.blogspot.com)
In C# (.NET), the DateTime() class is not accurate for high precision timing. Instead, use the Stopwatch() class if you need a timer. Most hardware and operating systems support a high-resolution performance counter that can be accessed through System.Diagnostics.Stopwatch.
Don't use DateTime() like this if you need accuracy:
using System; class Program { public static void Main() { DateTime start = DateTime.Now; // do timed work here DateTime stop = DateTime.Now; // don't do this. you won't get accurate timing Console.WriteLine("{0} ms", (stop - start).TotalMilliseconds); // definitely don't do this. you won't get accurate timing or full timer resolution Console.WriteLine("{0} ms", (stop - start).Milliseconds); } }
Stopwatch() uses operating system's high-resolution performance counter:
using System; using System.Diagnostics; class Program { public static void Main() { Stopwatch stopWatch = Stopwatch.StartNew(); // do timed work here stopWatch.Stop(); // don't do this. you won't get full timer resolution Console.WriteLine("{0} ms", stopWatch.ElapsedMilliseconds); // do this to get accurate high precision timing Console.WriteLine("{0} ms", stopWatch.Elapsed.TotalMilliseconds); } }
The Stopwatch class is in the System.Diagnostics namespace:
using System.Diagnostics;
Stopwatch measures elapsed time by counting timer ticks in the underlying timer mechanism. If the installed hardware and operating system support a high-resolution performance counter, then the Stopwatch class uses that counter to measure elapsed time. Otherwise, the Stopwatch class uses the system timer (DateTime class) to measure elapsed time.
To see if your system supports a high-resolution performance counter, check the Stopwatch.IsHighResolution property:
if (Stopwatch.IsHighResolution) Console.WriteLine("Using the system's high-resolution performance counter."); else Console.WriteLine("Using the DateTime class.");
To check the timing accuracy, use the Stopwatch.Frequency property:
long frequency = Stopwatch.Frequency; Console.WriteLine("Timer frequency in ticks per second: {0}", frequency); long nanosecPerTick = (1000L*1000L*1000L) / frequency; Console.WriteLine("Timer is accurate within {0} nanoseconds", nanosecPerTick);
1 comment:
You can combine this with the using() statement of C# to wrap a section of code that you'd like to log the start and end time for with very little effort. http://gist.github.com/571288 but replace the delegate/lambdas with the StopWatch functionality. :) I don't have this in the gist but it was one of the specialized classes I used in an auditing system to monitor critical calls to services and trigger alerts using the StopWatch.
Post a Comment