关于AverageTimer32 PerformanceCounter的困惑

10

我正在尝试设置一个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毫秒的连续曲线:Picture 我是否误解了AverageTimer32?我已经阅读了相关信息,但它有点令人困惑。然而,我已经看到做的几乎和我一样的实例,所以我想这应该可以工作。我只得到尖峰的原因是什么? 编辑 值得一提的是,TheMethodIWantToMeasure每5秒钟只会调用一次,我刚意识到我每5秒钟就会受到这个尖峰的干扰。但我不明白如果AverageTimer32使用公式((N 1 - N 0) / F) / (B 1 - B 0),这如何影响结果。它不应该取决于我多久存储N和B的值吗?
1个回答

2
您的答案在于您Permon设置的刷新/采样率。如果您删除~5s间隔或将其更改为~10ms之类的内容,您可能会注意到图形看起来更像您最初的预期。或者,将性能计数器刷新率更新为更高的间隔(30秒)也是一样的。(通过右键单击perfMon图表 ->属性 ->常规选项卡 ->每x秒取样一次来执行此操作)。
原因是perfMon每秒刷新1次(默认),然后需要显示您的平均值。因此,它会将该秒钟内添加到计数器中的“所有”操作绘制在图表上。
例如:如果您有3个操作在1秒钟内执行(0.1ms、0.2ms和0.3ms),perfMon会显示您的平均值为0.2ms,这是正确的。
为什么会出现间隙?我认为这是因为现在在计算平均值并看到“峰值”后,下一秒(当perfMon再次刷新时),它将计算0秒内的0个操作的平均值= 0。
如果您想真正看到您要测量的方法平均运行时间,请完全删除您的~5s间隔并让该方法持续运行即可。那应该解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接