52 votes

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?

77voto

Noldorin Points 67794

La classe Stopwatch , disponible depuis .NET 2.0, est la meilleure solution. Il s'agit d'un compteur de très haute performance précis à des fractions de milliseconde. Jetez un œil à la documentation MSDN , qui est assez claire.

EDIT: Comme suggéré précédemment, il est également conseillé d'exécuter votre code plusieurs fois afin d'obtenir un temps moyen raisonnable.

13voto

Joachim Sauer Points 133411

Exécutez votre code à plusieurs reprises. 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.

9voto

Simon Points 11945

Je trouve que ces 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

var tickTimer = new TickTimer();
//call a method that takes some time
DoStuff();
tickTimer.Stop();
Debug.WriteLine("Elapsed HighResElapsedTicks " + tickTimer.HighResElapsedTicks);
Debug.WriteLine("Elapsed DateTimeElapsedTicks " + tickTimer.DateTimeElapsedTicks);
Debug.WriteLine("Elapsed ElapsedMilliseconds " + tickTimer.ElapsedMilliseconds);
Debug.WriteLine("Start Time " + new DateTime(tickTimer.DateTimeUtcStartTicks).ToLocalTime().ToLongTimeString());

seront de sortie ce

Elapsed HighResElapsedTicks 10022886
Elapsed DateTimeElapsedTicks 41896
Elapsed ElapsedMilliseconds 4.18966178849554
Start Time 11:44:58

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

using (new DebugTimer("DoStuff"))
{
    //call a method that takes some time
    DoStuff();
}

seront de sortie ce à la fenêtre de débogage

DoStuff: Total 3.6299 ms

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

int x;
using (var iterationDebugTimer = new IterationDebugTimer("Add", 100000))
{
    iterationDebugTimer.Run(() =>
    {
        x = 1+4;
    });
}

Seront de sortie ce

Add: Iterations 100000 
Total 1.198540 ms 
Single 0.000012 ms

8voto

Brian Rasmussen Points 68853

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 votre nombre de façon 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 un peu 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 à l'IL 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.

3voto

Otávio Décio Points 44200

Utilisez un véritable profileur tel que dotTrace.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X