I'm working on a charge balancing system and thus I need to know the charge of each machine. PerformanceCounter seem the way to go, but creating the first one take between 38 and 60 sec. Each subsequent new Counter or 'NextValue' call is nearly instant however.
Here is the code I'm using :
[TestClass]
public class PerfMon
{
[TestMethod]
public void SimpleCreationTest()
{
Stopwatch Time = new Stopwatch();
Time.Start();
Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds);
// Create
PerformanceCounter RAM = new PerformanceCounter("Memory", "Available MBytes");
Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => RAM created");
PerformanceCounter CPU = new PerformanceCounter("Processor", "% Processor Time", "_Total");
Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => CPU created");
PerformanceCounter GC = new PerformanceCounter(".NET CLR Memory", "% Time in GC", "_Global_");
Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => GC created");
// Read
float Value = RAM.NextValue();
Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => RAM value is : " + Value);
Value = CPU.NextValue();
Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => CPU value is : " + Value);
Value = GC.NextValue();
Debug.WriteLine("Time is : " + Time.ElapsedMilliseconds + " => GC value is : " + Value);
}
}
Research
PerformanceCounter extremely slow in connecting remote server
Creating a new System.Diagnostics.PerformanceCounter is very slow
I tried using the other constructors and giving a precise 'MachineName' but it doesn't change anything.
Why a call to PerformanceCounter is slow?
http://craigandera.blogspot.fr/2005/06/performancecounter-constructor-horribly_21.html
According to this two threads, the problem seem to be about the fact that performance counters are a shared resource. However I don't understand how I could solve that.
Running Visual Studio in Administrator 'accelerate' the first creation from 38 sec to 26 sec, so it doesn't solve the problem either.
Thanks for your help.
I tried your code on my machine and I got >2.5 seconds for the constructor of the PerformanceCounter. I was not able to debug the .NET Source Code (I'm running VS2013 Express Edition, Windows 7 64b) but I did a series of experinets:
So I believe that there is no setup problem and the the answer is that PerformanceCounter constructor does complex work that takes a lot of time to execute.
All the events being monitored are software events, that can be tracked by the operating system. So I suppose that when a new PerformanceCounter object is created, the OS has to generate the current state of the machine. That possibly means getting information for all processes, and most of all, storing that information into a readable and fast accessible structure. What I observed is that the more active processes I have, the slower the PerformanceCounter is created. Also the more cores you have, probably the more data you have to collect.
In the last link you sent, there's a comment that seems to validate this theory but I suppose the spinlock part was optimized since 2005. Probably the measure of last resort is to debug the .NET source for constructing the PerformanceCounter. However I think that this is just how it's implemented.
What I would do is creating the PerformanceCounter objects I need during the initialization phase of the application.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With