2013-03-25 300 views
9

我试图设置一个PerformanceCounter来衡量某个方法的平均执行时间。我试过阅读AverageTimer32,我已经看了很多例子,但我似乎无法做到。关于AverageTimer32 PerformanceCounter的困惑

我设置的类别

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

你的答案在于你的permon设置的刷新率/采样率。如果您要取出〜5s间隔或至少将其更改为〜10ms之类的内容,您可能会注意到该图看起来更像您最初的预期。或者更新你的性能计数器刷新率到更高的间隔(30秒)将是相同的。 (通过右键单击perfMon图形 - >属性 - >常规选项卡 - > Sampe每隔x秒)执行此操作。

原因是perfMon每1秒刷新一次(默认),然后需要显示您的平均值。因此,需要“全部”您已添加到计数器中的操作,并将其绘制在图上。

示例:如果你有操作在第二执行(为0.1ms,0.2ms的& 0.3,MS),PERFMON将显示您的平均为0.2ms的,这是正确的。

为什么有差距?我相信这是因为现在在计算平均值之后,你会看到下一秒(当perfMon再次刷新时),它将计算0secs = 0的0次操作的平均值。

我的建议(如果你想真正看到你的TheMethodIWantToMeasure平均运行多长时间的平均值,就是到以你的〜5s间隔完全排除,并且简单地让方法连续运行,这应该会有所斩获,