I have written a piece of code like this below:
For testing i call the method ComputeAndLog and in the performance monitor i can see the non-zero average value. However as soon as i end my testing, the average performance counter value drops to zero. Any idea why thats the case ?
Probably i am using the wrong counters ?
The requirement I have is that I have a function and i have to calculate that on average, how much time that function takes to complete. Something like below:
void ComputeAndLog()
{
Stopwatch stopWatch = Stopwatch.StartNew();
FunctionWhoseAveragetTimeIsToBeMeasured();
write_counter(stopWatch.ElapsedTicks);
}
void write_counter(long timeForCompletion)
{
averageTimeCounter.IncrementBy(timeForCompletion);
averageBaseCounter.Increment();
}
Thanks xoxo
The AverageTimer32/64 does not calculate the average of all measurements you perform. Instead it provides the ration of your measurements to the number of operations you measured.
Basically, the issue with your code is the fact you are using a new timer every time you perform a measurement.
To understand how the AverageTimer works, it might be helpful to understand the formula behind it. This also answers why one needs an AverageBase to use an AverageTimer.
The formula for the AverageTimer is as following:
((N1 - N0) / F) / (B1 - B0)
with
In a nutshell the formular takes the current time in ticks and subtracts the previous one. The result divided by the factor F gives you the time you operation run since the last measurement taken at t-1.
Now you divide this by the current counter minus the counter before. This might be usually one. As a result you have the average time of your operation for one measurement.
Using the AverageBase you now can step over various measurement points. Think of a case where you can set the counter only every tenth operation you perform. Since your last measurement you would increment the AverageTimer by the new time measurement for all ten operations but increment the AverageBase by ten. Eventually, you will receive the average time for one operation (even if you have measured over all ten operation calls).
Looking at your code example you send in always the difference from timer start to timer end. Let this be a series of numbers like 10, 9, 8, 7 ,6 while increasing the AverageBase by 1.
For the second measurement you know will receive the following result:
(9 - 10) / F / (1 - 0) = -1 / F / 1
With F being 1 for simplicity you will get -1 as result.
The correct values to submit however should be
10, 19, 27, 34, 40
Again the same example we will get
(19 - 10) / F / (1 - 0) = 9 / F / 1
Again, with F being 1 you will have an average time of 9 for your operation. As you can see, the next value measured needs to be greater than the previous one so the AverageTimer works properly.
In your example you might use a global Stopwatch. Instead of starting it new, use Start() (not Restart()). As seen above, the counter will calculate the difference in time internally. That way you will get correct measurements.
Going to zero also makes sense, once you are done with your testing or your program ends, the counter will probably be closed and not provide any values anymore. You can do it manually by calling the Close() method on the counter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With