我写了一段如下代码:
为了测试,我调用方法ComputeAndLog,在性能监视器中,我可以看到非零平均值。但是,一旦我结束测试,平均性能计数器值就会降至零。知道为什么会这样吗?
我可能使用了错误的计数器?
我的要求是我有一个功能,我必须平均计算该功能需要多长时间才能完成。如下所示:
void ComputeAndLog()
{
Stopwatch stopWatch = Stopwatch.StartNew();
FunctionWhoseAveragetTimeIsToBeMeasured();
write_counter(stopWatch.ElapsedTicks);
}
void write_counter(long timeForCompletion)
{
averageTimeCounter.IncrementBy(timeForCompletion);
averageBaseCounter.Increment();
}
由于 XOXO
答案 0 :(得分:5)
AverageTimer32 / 64不计算您执行的所有测量的平均值。相反,它可以根据您测量的操作次数提供测量的比例。
基本上,代码的问题在于每次执行测量时都使用新的计时器。
要了解AverageTimer的工作原理,了解其背后的公式可能会有所帮助。这也解释了为什么需要一个AverageBase才能使用AverageTimer。
AverageTimer的公式如下:
((N1 - N0) / F) / (B1 - B0)
与
简而言之,公式采用当前时间刻度并减去前一个时间。结果除以因子F,可以得到自上次在t-1进行测量后运行的时间。
现在你将它除以当前计数器减去之前的计数器。这可能通常是一个。因此,您可以获得一次测量的平均操作时间。
使用AverageBase,您现在可以跨越各种测量点。考虑一种情况,您只能在每次执行第十次操作时设置计数器。从上次测量开始,您将通过新的时间测量将AverageTimer增加到所有十个操作,但将AverageBase增加十。最终,您将收到一次操作的平均时间(即使您已经测量了所有十次操作呼叫)。
查看您的代码示例,您始终发送从计时器开始到计时器结束的差异。这是一系列数字,如10,9,8,7,6,同时将AverageBase增加1。
对于第二次测量,您知道会得到以下结果:
(9-10)/ F /(1 - 0)= -1 / F / 1
为简单起见,F为1,结果为-1。
要提交的正确值应为
10,19,27,34,40
我们将再次使用相同的示例
(19 - 10)/ F /(1 - 0)= 9 / F / 1
同样,如果F为1,您的平均操作时间为9。 如您所见,下一个测量值需要大于前一个值,以便AverageTimer正常工作。
在您的示例中,您可以使用全球秒表。而不是重新启动它,使用Start()(而不是Restart())。如上所示,计数器将在内部计算时间差。这样你就可以得到正确的测量结果。
归零也是有道理的,一旦完成测试或程序结束,计数器可能会关闭,不再提供任何值。您可以通过调用计数器上的Close()方法手动完成。
答案 1 :(得分:0)
我有类似的问题。我在AverangeCounter的PerformanceMonitor中获得了很好的输出。但是在程序中,一个操作NextValue总是返回0.顺便在ElapsedTime计数器中,我想要的操作返回值相同。
然后我理解AverageTimer32的核心(我希望)。 你不应该希望AverageTimer32会显示一些工作的平均时间。它只是计时器,是一次操作的平均时间并显示它。如果没有工作,则不存在操作时间,并且您将具有0作为计数器的值。
如果我每次添加刻度来反击时都会使用NextValue返回秒数(因为据我所知它返回的是最后一个值,而不是平均值。一个AverageTimer32计数器的名称是任何人都可以误解的)。如果我缓存它然后我可以用更易读的形式转换它并将其用作程序中的计数器值(如果你在第二次收到0后立即询问NextValue)。
此外,我想纠正以前的答案。你应该使用
10,9,8,7,6
而不是
10,19,27,34,40
使用方法IncreaseBy和
时10,19,27,34,40
在RawValue中手动设置Stopwatch.GetTimestamp()时。