Is your first instinct doing something similar to this?
DateTime start = DateTime.Now;
//do stuff
DateTime end = DateTime.Now;
Console.WriteLine("Executed in {0} ms", (end - start).TotalMilliseconds);
..when you should actually be doing is this:Stopwatch stopwatch = Stopwatch.StartNew();
//do stuff
stopwatch.Stop();
Console.WriteLine("Executed in {0} ms", stopwatch.ElapsedMilliseconds);
Stopwatch vs. DateTime for benchmarking
Stopwatch resides in the System.Diagnostics namespace and is (on most systems) a high resolution timer. Unlike DateTime, Stopwatch is actually meant for diagnostics and benchmarking. DateTime.Now is limited to a resolution of about 10 ms, probably worse in most cases while Stopwatch has a much higher resolution at about 0.0005 ms (500 nano seconds, often even lower) which is a whole lot more suitable for benchmarking.
While milliseconds is a useful tool it may be deceiving, especially when comparing two snippets of code that both run for a long time. An alternative is measuring execution time in ticks instead. While a DateTime.Ticks-tick is 100 nano seconds the Stopwatch.ElapsedTicks is defined as:
long tick = (1000L*1000L*1000L) / Stopwatch.Frequency;
The Stopwatch.Frequency field reflects the frequency of the hardware high resolution counter on the current system and the above code would reflect how long a tick in Stopwatch.ElapsedTicks is. These counters usually tick millions of times a second. As you can tell, the difference is accuracy is ridiculous.
Some of the basic properties and methods in Stopwatch
Properties:
- Stopwatch.Elapsed – returns a TimeSpan
 - Stopwatch.ElapsedMilliseconds – returns a long
 - Stopwatch.ElapsedTicks – also returns a long. I prefer this property
 
There is the .Reset() and .Stop() methods that are, just as the above, pretty self explanatory. There is also a .Restart() method that is basically a shorthand for .Stop(), Reset() and Start(). most of the time I find I want to add to a counter or write something to Console or a log file somewhere between .Stop() and .Reset() which is why I seldom use .Restart().
An example benchmark using Stopwatch
In a previous post I compared counting the char ‘x’ in a string in a forward for loop and a for loop running backwards. Here is a simple example of what a benchmark could look like:
namespace BenchmarkExample
{
    using System;
    using System.Diagnostics;
 
    class ForwardBackwardBenchmark
    {
        public ForwardBackwardBenchmark()
        {
            //// create a 10000 character long string
            string s = new String('x', 10000);
 
            Stopwatch fwdSw = new Stopwatch();
            Stopwatch bwdSw = new Stopwatch();
 
            //// Set up some variables for displaying
            //// statistics in the end of the example
            int fwdCounter = 0;
            int bwdCounter = 0;
 
            //// Run the benchmark 10000 times
            for (int j = 9999; j >= 0; --j)
            {
                //// Loop forwards
                fwdSw.Start();
                for (int i = 0; i < s.Length; i++)
                {
                    if (s[i].Equals('x'))
                    {
                        ++fwdCounter;
                    }
                }
                fwdSw.Stop();
 
                //// Loop backwards
                bwdSw.Start();
                for (int i = s.Length - 1; i >= 0; --i)
                {
                    if (s[i].Equals('x'))
                    {
                        ++bwdCounter;
                    }
                }
                bwdSw.Stop();
            } //// Outer for-loop
 
            //// Output the result
            long f = fwdSw.ElapsedTicks;
            long b = bwdSw.ElapsedTicks;
 
            Console.WriteLine("Forward loop used {0} ticks.", f);
            Console.WriteLine("Backward loop used {0} ticks.", b);
 
            double r;
            r = Math.Round(((double)b / ((double)f)) * 100, 2);
 
            Console.WriteLine("Bwd used {0}% ticks compared to fwd", r);
            Console.WriteLine();
        }
    }
}
Exactly can understand to process of good example of the program.
ReplyDelete