性能计数器NextValue()非常慢(1,000多个计数器) [英] Performance Counters NextValue() Very Slow (1,000+ Counters)

查看:134
本文介绍了性能计数器NextValue()非常慢(1,000多个计数器)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的应用程序中,我们正在使用Windows性能计数器来存储我们的一些应用程序指标,这些指标随后将在某些Web服务中检索.

In our application, we are using the Windows Performance Counters to store some of our application metrics, which are later retrieved in some web services.

我从计数器读取值所花费的时间有问题.我已经浏览了我的应用程序的其余部分,一切都很好,在性能方面也不错,但是从循环(从List或数组)中读取计数器需要花费大量的时间.

I'm having an issue with the amount of time it takes to read the value from the counters. I've looked through the rest of my app and everything is fine, performance wise, but reading from the counters within a loop (from List or array) takes a painful amount of time.

示例代码:

// 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.其中很多时间为0毫秒,最高约为170毫秒,平均非零约为80-90毫秒.

In my testing of just the loop above, a list of 1,359 counters takes 20 seconds, and with a stopwatch in place, it seems the average time to read a counter value is either 0-10ms, or about 80-90ms. A lot of them take 0ms, the highest being about 170ms, with the average non-zero being about 80-90ms.

也许我太乐观了,但是我认为读取1,000个数字值仅需要几毫秒.

Maybe I am being too optimistic, but I would have figured that reading 1,000 numeric values should take only a few milliseconds. Is there a lot more processing going on here than I'm aware of?

我的逻辑后面实际上还有另一个循环,该循环为计算的计数器获取第二个值.这只会使情况变得更加糟糕. :)

I actually have another loop later in my logic that gets a second value for calculated counters. That just makes this doubly worse. :)

谢谢!

我将秒表包裹在秒表中,结果令我感到惊讶.甚至读取.RawValue的简单属性仍会花费大量时间.据我了解,所有计数器的工作原理基本相同,并且检索速度应该非常快;奇怪的是,我还看到一种模式,其中网络"类别的计数器需要更长的时间.

I wrapped the counter retrieval in a stopwatch and I'm surprised by the results. Reading even the simple property of .RawValue still takes an excessive amount of time. It's my understanding that counters all basically work the same, and retrieval should be incredibly fast; strangely I'm also seeing a pattern where counters for Networking categories take longer.

根据 http://joe.blog.freemansoft. com/2014/03/windows-performance-counters.html ,甚至不应该考虑Performance Counter服务的性能.

According to http://joe.blog.freemansoft.com/2014/03/windows-performance-counters.html, performance for the Performance Counter service shouldn't even be a consideration.

我已将一些秒表结果发布到以下pastebin: http://pastebin.com/raw.php?i = aDJk2Tru

I've posted some stopwatch results to the following 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范围内有很多读数.我真的不明白怎么回事.当然,一个计数器值应该与其他任何一个计数器值一样快,对吧?

As you can see in the paste, a lot of reads are 0, but there are a lot in the 50-100ms range. I don't really understand how that can be. Surely one counter value should be just as fast as any other, right?

推荐答案

这是我能够找到的有关计数器的信息.请原谅语法;这是我发送的有关此问题的电子邮件中的一部分.

Here’s what I've been able to find out about the counters. Please forgive the grammar; this was somewhat extracted from an email I sent out regarding this problem.

  • 至少在我的机器上有4-5秒的处理时间(不确定服务器上的情况是好是坏),可以从计数器类别中读取实例名称.这与类别中计数器的数量可以忽略不计.如果您不使用实例计数器,则可以避免这种情况.
  • 我们将所有柜台存储在一个类别中,因此,根据我们的情况,该类别不可避免地最终会拥有成千上万个柜台.在我的测试中,类别中的计数器越多,性能就越差.这似乎应该是有道理的,但是单个计数器的性能会受到当前内存中计数器的数量的影响,这是一个奇怪的相关性,也许是:
    • 共有8个计数器,每个计数器的读取时间约为1-2ms
    • 总共有256个计数器,每个计数器的读取时间约为15-18ms
    • 总共有512个计数器,每个计数器的读取时间约为30ms
    • 总共3,584个计数器(读取所有计数器),每个计数器的读取时间约为200ms
    • 系统中共有3,584个计数器(在内存中过滤,仅读取512个计数器),每个计数器的读取时间为50-90ms.不确定为什么这些速度比前一批512个计数器慢.
    • 我使用System.Diagnostics.Stopwatch为这些测试运行了几次以计时.
    • There is a 4-5 second processing time, on my machine at least (may be better or worse on server, not sure), to read the instance names from a counter category. This varies negligibly with the number of counters in a category. If you are not using instance counters, you can avoid this.
    • We store all of the counters in a single category, so it’s inevitable that category will eventually end up with thousands of counters, given our situation. In my testing, the more counters in a category, the worse the performance. This seems like it should make sense, but the performance of an individual counter is affected by the number of counters currently in memory, which is an odd correlation, maybe:
      • With 8 total counters, read time is about 1-2ms per counter
      • With 256 total counters, read time is about 15-18ms per counter
      • With 512 total counters, read time is about 30ms per counter
      • With 3,584 total counters (reading all counters), read time is about 200ms per counter
      • With 3,584 total counters in the system (filtered down in memory, reading only 512 counters), read time is anywhere from 50-90ms per counter. Not sure why these are slower than the previous batch of 512 counters.
      • I ran each of these tests a few times using System.Diagnostics.Stopwatch to time them.

      鉴于上面的数字,在我的计算机上,较慢的一端有512个计数器,每个计数器大约50毫秒,再加上实例查询和第二个计数器的读取,每个请求大约需要60秒.假设我们一次只处理512个计数器.我已经多次对计算机上的服务运行了完整查询,并且请求在60-65秒内持续完成.

      Given the numbers above, on my machine, with 512 counters at roughly 50ms each on the slower end, plus the instance query, and the second counter read, we’re looking at about 60 seconds per request. This is given that we’re working with only 512 counters at a time. I’ve run the full query against the service on my machine several times and the request consistently completes in 60-65 seconds.

      基于要评估的其他计数器的数量,我当然不会假设单个计数器的这种性能下降.在我的阅读中,Windows Performance Monitor系统应该是快速的,并且只有少量的集合就可以了.我们的用例可能不太适合,并且我们可能正在滥用系统.

      I certainly would not have assumed this type of performance degradation of single counters based on the number of other counters being assessed. In my reading, the Windows Performance Monitor system is supposed to be fast, and with small collections it certainly is. It’s possible that our use case is not a good fit and we may be abusing the system.

      鉴于我们可以控制创建计数器的方式,因此我们决定对方法进行一些更改.我们创建了许多类别,而不是创建几个具有多个计数器的类别,每个类别具有更少的计数器(每个类别4-8个计数器).这种方法使我们能够有效避免性能问题,并且计数器读取时间在0-1ms范围内.到目前为止,根据我们的经验,即使有100个新类别,每个类别都有几个计数器,也完全不会影响系统的性能.

      Given that we have control over how we create counters, we have decided to change our approach a bit. Instead of a few categories with many counters, we instead create many categories, each having fewer counters (4-8 counters per category). This approach has allowed us to effectively avoid the performance issue, and counter read times are in the 0-1ms range. In our experience so far, having even 100 new categories with a few counters each does not affect performance in the system at all.

      重要的是要注意,在处理大量其他计数器时,您需要解决默认情况下为性能计数器设置的内存限制.可以通过machine.config或注册表项来完成.可以在这里找到更多信息: http://msdn .microsoft.com/en-us/library/ms229387(v = vs.110).aspx

      It's important to note when dealing with a large number of additional counters, you will need to address the memory limitation that is set by default for Performance Counters. This can be done either via machine.config or a registry entry. More information can be found here: http://msdn.microsoft.com/en-us/library/ms229387(v=vs.110).aspx

      这篇关于性能计数器NextValue()非常慢(1,000多个计数器)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆