# Measuring a method executing time

I have been playing around with some improvements to some sort algorithms like Selection Sort and Merge Sort and I ended up needing some sort of measurement to check if my versions were any faster than the original algorithm form. I also had a need to implement some sort of time measurement before but never did it, so here came the chance. And so I ended up coding the following measurement method:

public static double Measure(Action action, bool print = true)
{
Stopwatch watch = new Stopwatch();
const int precision = 1; //estimated precision of 1 milisecond on my machine
const int error = 1; //max error
const int times = 10;
double min = double.MaxValue;
for (int i = 0; i < times; ++i)
{
int iterations = 0;
watch.Restart();
while (watch.Elapsed.Milliseconds < precision*(100-error))
{
action();
++iterations;
}
watch.Stop();
min = Math.Min(min, watch.Elapsed.Milliseconds*1000.0/iterations);
}

if(print)
Debug.WriteLine("The action takes {0:N4} nanos to complete", min);

return min;
}


Is this a well conducted measurement algorithm? Any suggestions or improvements that I could apply?

-
Can you explain what you are checking with watch.Elapsed.Milliseconds < precision*(100-error) condition? – Sergey Berezovskiy Feb 14 '14 at 12:56
I found that the stopWatch has a precision of about a milisecond. And so to only have a error of 1% i need to run a method at least during about 100 milliseconds, although this only applies to the methods that take only some nanoseconds to run. That's also why ChrisW suggested his approach. – Bruno Costa Feb 14 '14 at 13:49
So if my precision decreases (meaning that it would be bigger for example 2 milliseconds) I would need to test the method for about 200 milliseconds to have a 1% error. – Bruno Costa Feb 14 '14 at 15:32

The thing you're timing is:

while (watch.Elapsed.Milliseconds < precision*(100-error))
{
action();
++iterations;
}


The problem is that if action takes a very short time, then most of what you're timing is the time it takes to call the watch.Elapsed.Milliseconds property.

A more accurate timer would be something like:

int iterations = 1000;
watch.Restart();
while (iterations--)
{
action();
}
watch.Stop();


You would then need to do something to ensure you pick a suitable number of iterations (e.g. try again with 10 times as many iterations if the measured time is too short to be accurate).

-
You made a point there. I think that I could mix my code with yours. So I would find the number of iterations on 100 milliseconds and than measure the time again using your way. Hopefully will save some precious nanoseconds in measurament. – Bruno Costa Feb 14 '14 at 2:26