web-dev-qa-db-fra.com

Chronomètre et utilisation de System.DateTime.Now pour les événements de chronométrage

Je voulais suivre les performances de mon code, j'ai donc enregistré l'heure de début et de fin à l'aide de System.DateTime.Now. J'ai pris la différence entre les deux comme l'heure d'exécution de mon code.

J'ai cependant remarqué que la différence ne semblait pas exacte. J'ai donc essayé d'utiliser un objet Stopwatch. Cela s'est avéré beaucoup, beaucoup plus précis.

Quelqu'un peut-il me dire pourquoi Stopwatch serait plus précis que de calculer la différence entre une heure de début et une heure de fin à l'aide de System.DateTime.Now?

BTW, je ne parle pas d'un dixième de pour cent. J'obtiens une différence de 15 à 20%.

91
Randy Minder

Selon MSDN :

Le chronomètre mesure le temps écoulé en comptant les tics du minuteur dans le mécanisme de minuteur sous-jacent. Si le matériel et le système d'exploitation installés prennent en charge un compteur de performances haute résolution, la classe Chronomètre utilise ce compteur pour mesurer le temps écoulé. Sinon, la classe Chronomètre utilise le minuteur système pour mesurer le temps écoulé. Utilisez les champs Frequency et IsHighResolution pour déterminer la précision et la résolution de l'implémentation du chronométrage.

Il utilise une résolution/précision supérieure à DateTime.Now.

Vous pouvez également consulter ces liens connexes:

Environment.TickCount vs DateTime.Now

DateTime.Now est-il le meilleur moyen de mesurer les performances d'une fonction?

DateTime est assez bon pour la précision à la seconde probablement mais tout ce que je recommande StopWatch.

74
Kelsey

Il est préférable d'utiliser la classe Chronomètre car elle est beaucoup plus précise que la soustraction de valeurs DateTime:

Stopwatch s = Stopwatch.StartNew();
// Tested code here
s.Stop();
Console.WriteLine("Elapsed Time: {0} ms", s.ElapsedMilliseconds);

Malheureusement, ce simple morceau de code ne sera pas suffisant pour obtenir des mesures précises la plupart du temps, car il y a beaucoup d'activité sous le capot du système d'exploitation, ce qui peut voler du temps processeur et ralentir l'exécution de votre code. C'est pourquoi il est préférable d'exécuter les tests plusieurs fois, puis de supprimer les temps les plus bas et les plus élevés. Pour cette puprose, c'est une bonne solution d'avoir une méthode qui exécute le code testé plusieurs fois, supprime les temps les plus bas et les plus grands et calcule le temps moyen. J'ai publié un exemple de méthode de test dans mon blog .

29
Pavel Vladov

ce lien performances de la fonction de synchronisation traite de votre problème exact, en particulier de ce paragraphe:

Le problème est que, selon MSDN, la résolution de la fonction DateTime.Now est de 10+ millisecondes, et nous devons l'appeler deux fois! Cela introduirait donc un swing de 20+ ms dans votre mesure d'exécution. Comme nos appels de fonction sont souvent susceptibles d'être retournés beaucoup plus rapidement que cette fenêtre de 20 ms, ce n'est pas suffisant.

EDIT: Cela ressemble à la deuxième DateTime.Now est appelé à un moment différent de celui de la fin de la méthode du chronomètre.

8
Robb