HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Measuring a given method's execution time

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
methodtimemeasuringgivenexecution

Problem

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?

Solution

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).

Code Snippets

while (watch.Elapsed.Milliseconds < precision*(100-error))
{
    action();
    ++iterations;
}
int iterations = 1000;
watch.Restart();
while (iterations--)
{
    action();
}
watch.Stop();

Context

StackExchange Code Review Q#41597, answer score: 6

Revisions (0)

No revisions yet.