Reputation: 25
There may be a duplicate but I didn't know how to explain my problem.
I'm running performance timing of the Floyd Rivest Algorithm I implemented (on different cases) using the .NET Stopwatch.
To better understand the problem, here is the code.
I am executing the 3 following methods one after the other:
analysis.FRStopwatch(analysis.getOrderedArray()); analysis.FRStopwatch(analysis.getDescendingOrderedArray()); analysis.FRStopwatch(analysis.getUnorderedArray());
The method FRStopwatch(int[]) does the following:
public double FRStopwatch(int[] array)
{
frs = new FloydRivestSelection(array);
double avg = 0;
Stopwatch s = new Stopwatch();
for (int i = 0; i < k.Length; i++)
{
Thread.Sleep(10);
s.Start();
frs.Select(k[i]);
s.Stop();
avg = avg + (double)s.Elapsed.TotalMilliseconds;
s.Reset();
Console.WriteLine(avg);
}
avg = avg / (double)k.Length;
return avg;
}
The output I get is the following: Original Output
As one can see, the ordered array's timing is way larger than the others.
Then I commented out the first line shown:
analysis.FRStopwatch(analysis.getOrderedArray());
and executed only the remaining two in the following order:
analysis.FRStopwatch(analysis.getDescendingOrderedArray()); analysis.FRStopwatch(analysis.getUnorderedArray());
I got the following output: New Output It seems like the first method that uses the Stopwatch is working incorrectly (or the other two are working incorrectly?). How do I fix is so that the results are consistent? Does the problem have to do with my computer (CPU ticks etc)?
Upvotes: 1
Views: 853
Reputation: 13394
Those lines are problematic:
avg = avg + (double)s.Elapsed.TotalMilliseconds;
Console.WriteLine(avg);
You are increasing the average, but you output the sum. Try this instead to output the "current" average.
avg = avg + (double)s.Elapsed.TotalMilliseconds;
Console.WriteLine(avg / (i+1));
Or this, if you are interested in the runtimes of every single iteration:
Console.WriteLine(s.Elapsed.TotalMilliseconds);
//reset after instead of before of course
s.Reset();
Upvotes: 1
Reputation: 13795
A single sample of a small request is subject to too many variables.
To get a better indication of performance, run each a few thousand times (say 6000), then discard the first 1000 or so results to get rid of any warmup factors (JIT / caching etc).
Take your results and divide by 5000 to get an average execution time. this approach will help you keep your sanity and give a better indication of performance.
Upvotes: 0
Reputation: 27871
You are printing to the console the accumulative sum of the times, not the average nor the individual times.
I suggest that you print the individual times like this:
s.Start();
frs.Select(k[i]);
s.Stop();
var elapsed = (double)s.Elapsed.TotalMilliseconds;
avg = avg + elapsed; //it is really sum, not avg
s.Reset();
Console.WriteLine(elapsed);
I guess that the fist iteration for the first method will consume the largest amount of time probably because of JIT compilation. If you print individual times, you will see this clearly.
Also, I suggest you change the variable name from avg
to sum
, and only calculate the average after the loop.
Upvotes: 0