我正在尝试测量在生产服务器上执行一段代码所需的时间。我想实时监控这些信息,所以我决定给性能分析器一个高手。我从MSDN了解到,我需要同时创建一个AverageTimer32和一个AverageBase性能计数器。我在程序中递增计数器,我可以看到CallCount上下移动,但AverageTime始终为零。我做错了什么?
这是一段代码:
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();
答案 0 :(得分:4)
首先,附加到性能计数器非常昂贵,因此您应该尝试将全局实例保留给它们,而不是每次都打开和关闭它们。
您似乎有正确的想法,这几乎就是我们在性能监控代码中所做的。但是我们不会在更新这些之前立即执行.NextValue - 所以我会尝试最初停止这样做。
你是否也确定Environment.TickCount - init_call_time不是这么短的一段时间,它的评估结果为0? Environment.TickCount没有很好的分辨率,System.Diagnostics.Stopwatch类具有更好的准确性。
答案 1 :(得分:2)
假设你不是多线程的,那么这应该是
// 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
如果您处于多线程情况,那么:
// 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();
答案 2 :(得分:0)
AverageTimer32按两次调用之间经过的时间递增,并且每次执行的操作的AverageBase递增1。
这是PerformanceCounterType的文档。 http://msdn.microsoft.com/en-us/library/system.diagnostics.performancecountertype.aspx
这是另一种资源: http://www.codeproject.com/KB/dotnet/perfcounter.aspx