Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use PerformanceCounterType AverageTimer32?

Tags:

performance

c#

I'm trying to measure the time it takes to execute a piece of code on my production server. I'd like to monitor this information in real time, so I decided to give Performance Analyser a whizz. I understand from MSDN that I need to create both an AverageTimer32 and an AverageBase performance counter, which I duly have. I increment the counter in my program, and I can see the CallCount go up and down, but the AverageTime is always zero. What am I doing wrong?

Here's a snippit of code :

long init_call_time = Environment.TickCount;

// ***
// Lots and lots of code...
// ***

// Count number of calls
PerformanceCounter perf = 
    new PerformanceCounter("Cat", "CallCount", "Instance", false);
perf.Increment();
perf.Close();

// Count execution time
PerformanceCounter perf2 = 
    new PerformanceCounter("Cat", "CallTime", "Instance", false);
perf2.NextValue();
perf2.IncrementBy(Environment.TickCount - init_call_time);
perf2.Close();

// Average base for execution time
PerformanceCounter perf3 = 
    new PerformanceCounter("Cat", "CallTimeBase", "Instance", false);
perf3.Increment();
perf3.Close();

perf2.NextValue();
like image 617
Patrick J Collins Avatar asked Aug 03 '09 08:08

Patrick J Collins


2 Answers

First off, attaching to performance counters is quite expensive, so you should try and keep global instances live to them instead of opening and closing them each time.

You seem to have the right idea, thats pretty much what we do in our performance monitoring code. However we do not do .NextValue immediately prior to updating these - so I'd try stopping doing that initially.

Are you also sure that Environment.TickCount - init_call_time isnt such a small period of time that it evaluates to 0? Environment.TickCount doesnt have great resolution, the System.Diagnostics.Stopwatch class has much better accuracy.

like image 124
Kieran Benton Avatar answered Oct 21 '22 17:10

Kieran Benton


Assuming you are not multi threaded then this should be

// cached somewhere
var perf2 = new PerformanceCounter("Cat", "CallTime", "Instance", false);
var sw = new Stopwatch();

// where ever you are setting init_call_time
sw.Start();

// then when the task has finished
sw.Stop();
perf2.RawValue = sw.ElapsedMilliseconds; // or tick, whatever you want to use

If you are in a multi threaded situation then:

// cached somewhere
var perf2 = new PerformanceCounter("Cat", "CallTime", "Instance", false);

[ThreadStatic]
Stopwatch sw;

// where ever you are setting init_call_time
if (sw == null)
    sw = new Stopwatch();
sw.Start();

// then when the task has finished
sw.Stop();
perf2.IncrementBy(sw.ElapsedMilliseconds); // or tick, whatever you want to use
sw.Reset();
like image 30
ShuggyCoUk Avatar answered Oct 21 '22 17:10

ShuggyCoUk