Windows est un peu notoire d'être lent à chaque fois que vous faites quelque chose avec tous les processus en cours d'exécution sur une machine. Mais c'est excessif. Il y a quelque chose de pourri dans l'état de PerformanceCounter, j'ai eu le premier indice de this question. Quelque chose que vous pouvez facilement visualiser dans votre propre programme de test en modifiant le Console.WriteLine() appel:
Console.Write($"Time taken to read {pcs.Count()} performance counters:");
Console.WriteLine($"{sw.ElapsedMilliseconds}ms, {GC.CollectionCount(2)} collections");
Sortie sur ma machine:
Time taken to read 124 performance counters: 1633ms, 15 collections
Time taken to read 124 performance counters: 923ms, 30 collections
Time taken to read 124 performance counters: 928ms, 45 collections
Time taken to read 124 performance counters: 934ms, 59 collections
Time taken to read 124 performance counters: 922ms, 74 collections
Time taken to read 124 performance counters: 925ms, 89 collections
...etc
Ou en d'autres termes, une collection complète des ordures pour chaque ~ 8 appels à PerformanceCounter.NextValue(). Aie. Oui, ça va beaucoup ralentir votre programme.
C'est un comportement remarquablement étrange, pour le moins. Je ne trouve pas de bons indices dans la classe PerformanceCounter elle-même, le code semble très innocent. Il y a un gros morceau de code non géré sous le capot qui est difficile à voir (C: \ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ PerfCounter.dll) mais en regardant ses dépendances ne fournissent pas de preuve convaincante qu'il est responsable. Cela se produit à la fois sur les versions d'exécution v2.0.50727 et v4.0.30319, donc un hack malheureux dans V4.x ne l'explique pas facilement. Ce n'est pas un bon multiple de 8 donc un simple compteur qui oblige les finaliseurs à s'exécuter ne l'explique pas facilement. Ce n'est pas le compteur de performance natif, l'interroger avec WMI ne déclenche aucune collection. Il n'est pas spécifique aux compteurs de mémoire, demandant, disons, "Thread Count" le fait aussi. Pourrait avoir quelque chose à voir avec la version Windows, le mien est Win10 version 1607 (ne peut pas facilement tester un autre).
Microsoft doit s'impliquer dans ce processus. L'auteur de la question que j'ai liée semble avoir créé un bug feedback report for it, j'ai ajouté ce Q + A comme preuve à l'appui. Gardez un oeil sur le rapport de rétroaction, votez pour cela, j'espère qu'ils vont commencer à prêter attention. Ou contactez le support technique Microsoft directement si vous ne voulez pas attendre.
En attendant, vous pouvez obtenir l'espace de noms System.Management.L'utilitaire de code WMI Creator est très pratique pour générer automatiquement le code:
...
using System.Management; // Project > Add Reference required
public static void QueryWorkingset() {
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
"SELECT Name, WorkingSetPrivate FROM Win32_PerfRawData_PerfProc_Process");
foreach (ManagementObject queryObj in searcher.Get()) {
Console.WriteLine("{0}: {1}", queryObj["Name"], queryObj["WorkingSetPrivate"]);
}
}
Encore aucun démon de vitesse, prend environ 1,0 msec par processus sur ma machine. Mais ne brûle pas 100% core comme le fait PerformanceCounter et pas de collections forcées.
Vous pouvez toujours [utiliser l'API Win32 brute] (http://mjs5.com/2016/06/05/c-get-basic-memory-information-using-getperformanceinfo-api/) ou exécuter un quelques tâches en parallèle. – stuartd
Incidemment, la [page MSDN de performance de la mémoire] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa965225 (v = vs.85) .aspx) indique _ "informations sur la performance de la mémoire est disponible du gestionnaire de mémoire via les compteurs de performance système et via des fonctions telles que GetPerformanceInfo, GetProcessMemoryInfo et GlobalMemoryStatusEx Des applications telles que le Gestionnaire des tâches Windows, le moniteur de fiabilité et de performances et l'outil Explorateur de processus utilisent des compteurs de performance pour afficher les informations de mémoire. et pour les processus individuels. "_ – stuartd
@stuartd vous savez quoi, j'ai complètement oublié le filetage. Je pourrais en effet les faire tourner en parallèle! Je me demande quel impact sur la performance cela aurait .. – mikeysee