在我们的应用程序中,我们使用Windows性能计数器来存储我们的一些应用程序指标,这些指标稍后会在某些Web服务中检索。
我遇到了从计数器读取值所花费的时间问题。我查看了我的应用程序的其余部分,一切都很好,性能明智,但从循环中的计数器(从列表或数组)中读取需要花费大量时间。
示例代码:
// This triggers a read of the counter's initial value (1000ms delay following for calculated counters)
counters.ToList().ForEach(counter => counter.NextValue());
在我上面的循环测试中,1,359个计数器的列表需要20秒,并且使用秒表,似乎读取计数器值的平均时间是0-10ms,或大约80-90ms。其中很多都需要0ms,最高约为170ms,平均非零值约为80-90ms。
也许我太乐观了,但我认为读取1,000个数值应该只需要几毫秒。这里有更多的处理工作比我知道的还多吗?
我实际上在我的逻辑中有另一个循环,它获得计算计数器的第二个值。这只会使情况变得更糟。 :)
谢谢!
我将计数器检索包裹在秒表中,我对结果感到惊讶。阅读.RawValue
的简单属性仍然需要花费过多的时间。据我所知,计数器基本上都是一样的,检索应该非常快;奇怪的是,我也看到了网络类别的计数器需要更长时间的模式。
根据http://joe.blog.freemansoft.com/2014/03/windows-performance-counters.html,性能计数器服务的性能甚至不应该是一个考虑因素。
我已将一些秒表结果发布到以下pastebin:http://pastebin.com/raw.php?i=aDJk2Tru
我的代码如下:
Stopwatch t;
foreach (var c in counters)
{
t = Stopwatch.StartNew();
var r = c.RawValue;
Debug.WriteLine(t.ElapsedMilliseconds.ToString("000") + " - " + c.CategoryName + ":" + c.CounterName + "(" + c.CounterType + ") = " + r);
}
正如您在粘贴中看到的,很多读取都是0,但在50-100ms范围内有很多。我真的不明白这是怎么回事。当然,一个计数器值应该和其他任何一个一样快,对吗?
答案 0 :(得分:7)
这是我能够找到的关于计数器的信息。请原谅语法;这是从我发出的关于这个问题的电子邮件中提取的。
System.Diagnostics.Stopwatch
计算了几次这些测试以计时。鉴于上面的数字,在我的机器上,慢速端有512个计数器,大约50ms,加上实例查询,第二个计数器读取,我们每个请求大约需要60秒。这是因为我们一次只使用512个计数器。我已经多次针对我的机器上的服务运行完整查询,并且请求在60-65秒内一直完成。
基于所评估的其他计数器的数量,我当然不会假设单个计数器的这种性能下降。在我的阅读中,Windows性能监视器系统应该是快速的,并且当然是小型集合。我们的用例可能不太合适,我们可能会滥用系统。
鉴于我们已经控制了我们如何创建计数器,我们决定改变我们的方法。我们改为创建许多类别,而不是几个具有许多计数器的类别,每个类别都有较少的计数器(每个类别4-8个计数器)。这种方法使我们能够有效地避免性能问题,并且计数器读取时间在0-1ms范围内。根据我们迄今为止的经验,即使是100个新类别,每个类别都有几个计数器,也不会影响系统的性能。
在处理大量其他计数器时需要注意的是,您需要解决默认情况下为性能计数器设置的内存限制。这可以通过machine.config或注册表项来完成。可以在此处找到更多信息:http://msdn.microsoft.com/en-us/library/ms229387(v=vs.110).aspx