关于AverageTimer32 PerformanceCounter的困惑

Joe*_*oel 10 .net c# performancecounter

我正在尝试设置一个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);
Run Code Online (Sandbox Code Playgroud)

然后我创建了计数器

PC = new PerformanceCounter(categoryName, counterName, false);

BPC = new PerformanceCounter(categoryName, baseCounterName, false);

PC.RawValue = 0;
BPC.RawValue = 0;
Run Code Online (Sandbox Code Playgroud)

最后,我每次调用方法时记录经过的时间

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();
}
Run Code Online (Sandbox Code Playgroud)

这样做,我最终得到的结果是性能监视器看起来像这样.我得到尖峰而不是50毫秒左右的连续曲线: 图片

我误解了AverageTimer32吗?我读过它,但有点令人困惑.但是,我看到的例子和我几乎完全一样,所以我猜它应该有效.可能是什么原因导致我只有尖峰?

编辑 值得一提的TheMethodIWantToMeasure是,每隔约5秒调用一次,我才意识到我每隔~5秒就会得到一个尖峰.但是,如果AverageTimer32使用公式((N 1 -N 0)/ F)/(B 1 -B 0),我不明白如何影响结果.它不应该取决于我为N和B存储值的频率?

Nie*_*ter 2

您的答案在于您的 permon 设置的刷新/采样率。如果您要去掉~5s间隔或至少将其更改为~10ms之类的值,您可能会注意到图表看起来更像您最初预期的那样。或者将性能计数器刷新率更新为更高的间隔(30 秒)也是一样的。(通过右键单击 perfMon 图表 -> 属性 -> 常规选项卡 -> 每 x 秒采样一次)。

原因是 perfMon 每 1 秒刷新一次(默认情况下),然后需要显示您的平均值。因此,它会获取您在那一秒添加到计数器中的“所有”操作并将其绘制在图表上。

示例:如果您每秒执行3 个操作( 0.1ms、0.2ms 和 0.3,ms),perfMon 将显示您的平均值为0.2ms,这是正确的。

为什么会有间隙?我相信这是因为现在计算出平均值后,您会看到“尖峰”,下一秒(当 perfMon 再次刷新时),它将计算 0 秒内 0 次操作的平均值 = 0。

TheMethodIWantToMeasure我的建议(如果您想真正了解平均运行时间的平均值) ,就是完全取消大约 5 秒的间隔,然后让该方法继续运行。这应该可以解决问题。