Comment mesurer les performances du code dans .NET?
Je suis en train de faire un peu de réel rapide et sale benchmarking sur une seule ligne de code C# à l'aide de DateTime:
long lStart = DateTime.Now.Ticks;
//do something
long lFinish = DateTime.Now.Ticks;
Le problème est dans les résultats:
Heure De Début [633679466564559902] Heure De Fin [633679466564559902] Heure De Début [633679466564569917] Heure De Fin [633679466564569917] Heure De Début [633679466564579932] Heure De Fin [633679466564579932]
...et ainsi de suite.
Étant donné que le début et la fin sont identiques, les Tiques n'est évidemment pas granulaire assez.
Alors, comment puis-je mieux mesurer la performance?
- veuillez indiquer la langue
- Si les tiques n'est pas granuleux assez, je ne serais pas trop se préoccuper de la performance 8)
- double possible de l'analyse comparative des petits exemples de code en C#, cette mise en œuvre peut-elle être améliorée?
- Double Possible de Mesurer les délais d'exécution du code
Vous devez vous connecter pour publier un commentaire.
La
Stopwatch
classe, qui est disponible depuis .NET 2.0, est la meilleure façon d'aller pour cela. C'est un très haut de compteur de performance précis pour une fraction de milliseconde.Jetez un oeil à la La documentation MSDN, ce qui est assez clair.
EDIT: Comme suggéré précédemment, il est également conseillé d'exécuter votre code un certain nombre de fois afin d'obtenir une moyenne raisonnable de temps.
Exécuter votre code plusieurs fois. Le problème semble être que votre code s'exécute beaucoup plus rapidement que la granularité de votre instrument de mesure. La solution la plus simple pour cela est d'exécuter votre code beaucoup, beaucoup de fois (en milliers, peut-être des millions) et ensuite calculer la moyenne des temps d'exécution.
Edit: Aussi, en raison de la nature de l'actuel de l'optimisation des compilateurs (et des Machines Virtuelles telles que le CLR et la JVM), il peut être très trompeur pour mesurer la vitesse d'exécution d'une seule ligne de code, depuis la prise de mesure peut influencer la vitesse de beaucoup. Une meilleure approche serait de profil de l'ensemble du système (ou au moins de plus gros blocs) et de vérifier où les goulets d'étranglement.
- Je trouver ces très utiles
http://accelero.codeplex.com/SourceControl/changeset/view/22633#290971
http://accelero.codeplex.com/SourceControl/changeset/view/22633#290973
http://accelero.codeplex.com/SourceControl/changeset/view/22633#290972
TickTimer est un coupé copie de Chronomètre démarre quand construits et ne prend pas en charge le redémarrage. Il sera également vous informer si le matériel actuel ne prend pas en charge la résolution de synchronisation (Chronomètre avale ce problème)
Donc ce
sera de sortie ce
DebugTimer est un wrapper pour TickTimer qui écrira le résultat de Débogage. (note: il prend en charge le modèle Jetable)
Donc ce
sera de sortie ce à la fenêtre de débogage
IterationDebugTimer est pour chronométrer combien de temps il faut pour exécuter une opération plusieurs fois et écrire le résultat de Débogage. Il permettra également d'effectuer un premier cycle qui n'est pas inclus de manière à ignorer les temps de démarrage. (note: il prend en charge le modèle Jetable)
Donc ce
Sera de sortie ce
Juste pour ajouter à ce que d'autres ont déjà dit à propos de l'aide d'un Chronomètre et de mesure des moyennes.
Assurez-vous d'appeler votre méthode avant de mesurer. Sinon, vous permettra de mesurer le temps nécessaire pour JIT compiler le code. Qui peut biaiser les chiffres de votre activité de manière significative.
Aussi, assurez-vous de mesurer la libération code de mode que des optimisations sont désactivés par défaut pour les versions de débogage. Réglage de débogage de code est inutile à mon humble avis.
Et assurez-vous que vous êtes en mesure de ce que vous voulez mesurer. Lorsque les optimisations coup de pied dans, le compilateur/compilateur JIT peut réorganiser le code ou le supprimer entièrement, de sorte que vous pouvez vous retrouver à mesurer quelque chose d'un peu différent de celui prévu. Au moins prendre un coup d'oeil au code généré pour assurez vous que le code n'a pas été dépouillé.
En fonction de ce que vous essayez de mesurer gardez à l'esprit, qu'un réel système mettra l'accent sur l'exécution différemment qu'une application de test. Certains problèmes de performances sont liées par exemple à la manière dont les objets sont les ordures collectées. Ces problèmes ne seront généralement pas dans une simple application de test.
En fait, le meilleur conseil est de mesurer les systèmes réels avec des données réelles de bac à sable des tests, peut être très imprécise.
Utiliser un vrai profiler comme dotTrace.
Échantillon pour
Stopwatch
classeVous pouvez utiliser le
Stopwatch
, en supposant que vous utilisez .NET 2.0 ou plus récente.La
Stopwatch
classe a aussi des publique champ en lecture seuleIsHighResolution
qui vous permettra de savoir si le chronomètre est basé sur une haute résolution de compteur de performance. Si ce n'est pas, il est basé sur le système de minuterie.Je ne suis pas sûr de ce qu'il faut pour que le chronomètre à être basé sur haute résolution de compteur de performance. Il y a quelques appels de l'API, mais je me dis que si le chronomètre n'a pas une haute résolution, l'API n'est probablement pas là.
Voir la réponse à la Est De Type DateTime.Maintenant, la meilleure façon de mesurer un rendement de la fonction? pour une explication ou lire mon blog sur la mesure de la performance
Le problème est que DateTime a une résolution d'environ 15ms, il ne peut pas être plus précis que ça. Chronomètre, cependant, peut.
Voici une belle écriture à la MSDN sur la façon de Mettre en œuvre une Permanence de la mise à Jour, de Temps à Haute Résolution Fournisseur pour Windows
Voici la l'exemple de code source pour l'article (C++).
https://andreyakinshin.gitbooks.io/performancebookdotnet/content/science/microbenchmarking.html
https://github.com/PerfDotNet/BenchmarkDotNet
"En effet, microbencmarking est très dur. Si une opération ne prend que 10–100ns, l'opération de mesure est un grand défi. Je vous suggère d'utiliser BenchmarkDotNet pour tes repères. C'est une bibliothèque qui peut vous aider à faire une honnête de référence et d'obtenir des mesures avec une bonne précision. Bien sûr, vous pouvez écrire de référence, sans autres bibliothèques. Dans cette section, nous expliquons pourquoi il est probablement une mauvaise idée et ce que vous devriez savoir avant de commencer."
Ce projet de code article montre comment utiliser la haute performance de la minuterie de mesure de la vitesse d'exécution de votre code:
http://www.codeproject.com/KB/cs/highperformancetimercshar.aspx
Ici vous pouvez trouver un certain nombre de l'open source C# profileurs:
http://csharp-source.net/open-source/profilers
Une autre option est d'avoir la minuterie-code inséré automatiquement avec Fody. Cela rend votre code beaucoup plus facile à lire comme il se sépare de votre transversales préoccupations. Je pense que c'est proche de ce qui est appelé La Programmation Orientée Aspects, mais fait au moment de la compilation.
Voir https://github.com/Fody/MethodTimer pour la fody addon qui n'méthode de synchronisation.
Citant le fichier Readme:
Avec un intercepteur, quelque part dans votre assemblée:
Votre code,
Est compilé à ceci:
Jetables style
Stopwatch
qui fonctionne le mieux pour moi.Et puis:
Mes préférences vont pour BenchmarkDotNet mentionné par @Evgeniy. Probablement sa réponse est ignoré car il n'est pas extrait de code, mais c'est une chose de complexe, il vaut la peine au moins de prendre un coup d'oeil dans la bibliothèque avant d'aller la tête la première dans quelque chose de sur mesure.
Et parce que certains de code attrape toujours des yeux, voici l'exemple de la cité de site:
Parfois, il peut être préférable de chercher à comprendre pourquoi vous avez besoin de temps de l'opération? Est-il lent? Ou vous êtes simplement curieux? Première règle de l'optimisation est "ne fais pas cela". Ainsi, en fonction de ce que vous êtes réellement en mesure, pourrait changer l'opinion sur ce qui est le meilleur outil adapté à la tâche.
Plus facile d'utiliser un profiler comme Les FOURMIS Performance Profiler, ou l'un des autres qui sont disponibles.
J'ai fait une extension qui renvoie millisecondes à partir de tiques.
Utilisation:
J'ai fait une méthode très simple qui mesure la vitesse d'exécution d'un Action, qui a pour moi l'avantage que je peux le réutiliser à chaque fois que j'en ai besoin, et selon le code j'ai à mesure.
Pour moi un DateTime en avait assez, mais il est facilement adaptable à partir de DateTime pour Chronomètre.
Comment l'utiliser?:
ou:
Pour mesurer le rendement de la différence entre les mesures-je utiliser cette classe. Le Chronomètre de la classe n'a pas le
Split
méthode.