我正在尝试设置PerformanceCounter
来衡量某种方法的平均执行时间。我试着阅读AverageTimer32
,我看了很多例子,但我似乎无法做到正确。
我设置了类别
CounterCreationDataCollection CCDC = new CounterCreationDataCollection();
// Add the counter.
CounterCreationData averageTimer32 = new CounterCreationData();
averageTimer32.CounterType = PerformanceCounterType.AverageTimer32;
averageTimer32.CounterName = counterName;
CCDC.Add(averageTimer32);
// Add the base counter.
CounterCreationData averageTimer32Base = new CounterCreationData();
averageTimer32Base.CounterType = PerformanceCounterType.AverageBase;
averageTimer32Base.CounterName = baseCounterName;
CCDC.Add(averageTimer32Base);
// Create the category.
PerformanceCounterCategory.Create(categoryName, "Demonstrates usage of the AverageTimer32 performance counter type", PerformanceCounterCategoryType.SingleInstance, CCDC);
然后我创建了计数器
PC = new PerformanceCounter(categoryName, counterName, false);
BPC = new PerformanceCounter(categoryName, baseCounterName, false);
PC.RawValue = 0;
BPC.RawValue = 0;
最后,我每次调用方法时记录经过的时间
private void TheMethodIWantToMeasure() {
Stopwatch stopwatch = Stopwatch.StartNew();
// Fake work that take ~50ms
Thread.Sleep(50 + random.Next(-10, 10));
stopwatch.Stop();
PC.IncrementBy(stopwatch.ElapsedTicks);
BPC.Increment();
}
这样做,我最终得到的结果是性能监视器看起来像这样。我得到尖峰而不是50毫秒左右的连续曲线:
我误解了AverageTimer32
吗?我读过它,但有点令人困惑。但是,我看到的例子和我几乎完全一样,所以我猜它应该有效。可能是什么原因导致我只有尖峰?
修改
值得一提的是TheMethodIWantToMeasure
每隔约5秒调用一次,我才意识到我每隔~5秒就会得到一次尖峰。但是如果AverageTimer32
使用公式((N 1 -N 0)/ F)/(B 1 -B 0),我不明白这会如何影响结果。它不应该取决于我存储N和B的值的频率吗?
答案 0 :(得分:2)
您的答案取决于permon设置的刷新/采样率。如果您要取出 ~5s 间隔或至少将其更改为 ~10ms ,您可能会注意到图表看起来有点像您最初预期。或者,将性能计数器刷新率更新到更高的间隔(30秒)也是一样的。 (通过右键单击perfMon图表 - >属性 - >常规选项卡 - >每隔x秒Sampe )来执行此操作。
原因是perfMon每1秒刷新一次(默认情况下),然后需要显示平均值。所以需要" 所有"您在此时间点添加到计数器的操作,并将其绘制在图表上。
示例:如果您在一秒内执行 3 操作( 0.1ms,0.2ms& 0.3,ms ),则perfMon将将您的平均值显示为 0.2ms ,这是正确的。
为什么会有差距?我相信它是因为现在计算出你的平均值并且你看到你的" Spike",下一秒(当perfMon再次刷新时),它将在0secs = 0中计算0次操作的平均值。
我的建议(如果你想真正看到你的TheMethodIWantToMeasure
平均运行时间的平均值,那么完全取消你的~5s间隔并简单地让方法继续运行。这应该可以解决问题。