Question Est-ce que DateTime.Now est le meilleur moyen de mesurer les performances d'une fonction?


J'ai besoin de trouver un goulot d'étranglement et de mesurer le plus précisément possible le temps.

L'extrait de code suivant est-il le meilleur moyen de mesurer la performance?

DateTime startTime = DateTime.Now;

// Some execution process

DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);

433
2017-08-26 17:09


origine


Réponses:


Non ce n'est pas. Utilisez le Chronomètre (dans System.Diagnostics)

Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

Chronomètre vérifie automatiquement l'existence de minuteries de haute précision.

Il est important de mentionner que DateTime.Now est souvent un peu plus lent que DateTime.UtcNow en raison du travail qui doit être fait avec des fuseaux horaires, DST et autres choses de ce genre.

DateTime.UtcNow a généralement une résolution de 15 ms. Voir Le blog de John Chapman sur DateTime.Now précision pour un bon résumé.

Question intéressante: le chronomètre se rabat sur DateTime.UtcNow si votre matériel ne prend pas en charge un compteur haute fréquence. Vous pouvez vérifier pour voir si Stopwatch utilise du matériel pour atteindre une grande précision en regardant le champ statique Stopwatch.IsHighResolution.


602
2017-08-26 17:13



Si vous voulez quelque chose de rapide et de sale, je vous suggère d’utiliser plutôt Chronomètre pour une plus grande précision.

Stopwatch sw = new Stopwatch();
sw.Start();
// Do Work
sw.Stop();

Console.WriteLine("Elapsed time: {0}", sw.Elapsed.TotalMilliseconds);

Alternativement, si vous avez besoin de quelque chose d'un peu plus sophistiqué, vous devriez probablement envisager d'utiliser un profileur tiers tel que FOURMIS.


88
2017-08-26 17:15



Cet article dit que tout d'abord vous devez comparer trois alternatives, Stopwatch, DateTime.Now ET DateTime.UtcNow.

Cela montre également que dans certains cas (quand le compteur de performance n'existe pas), Stopwatch utilise DateTime.UtcNow + un traitement supplémentaire. À cause de cela, il est évident que dans ce cas, DateTime.UtcNow est la meilleure option (parce que d'autres l'utilisent + un traitement)

Cependant, comme il se trouve, le compteur existe presque toujours - voir Explication sur le compteur de performance à haute résolution et son existence liée à .NET Stopwatch?.

Voici un graphique de performance. Notez à quel point le coût des performances d'UtcNow est faible par rapport aux alternatives:

Enter image description here

L'axe X est la taille des données de l'échantillon et l'axe Y est l'heure relative de l'exemple.

Une chose Stopwatch est mieux à, c'est qu'il fournit des mesures de temps de résolution plus élevée. Une autre est sa nature plus OO. Cependant, créer un wrapper OO autour UtcNow ne peut pas être difficile


51
2017-08-08 18:04



Il est utile de pousser votre code d'évaluation dans une classe / méthode d'utilité. le StopWatch classe n'a pas besoin d'être Disposed ou Stopped en cas d'erreur Donc, le code le plus simple pour temps certains action est

public partial class With
{
    public static long Benchmark(Action action)
    {
        var stopwatch = Stopwatch.StartNew();
        action();
        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }
}

Exemple de code d'appel

public void Execute(Action action)
{
    var time = With.Benchmark(action);
    log.DebugFormat(“Did action in {0} ms.”, time);
}

Voici la version de la méthode d'extension

public static class Extensions
{
    public static long Benchmark(this Action action)
    {
        return With.Benchmark(action);
    }
}

Et exemple de code d'appel

public void Execute(Action action)
{
    var time = action.Benchmark()
    log.DebugFormat(“Did action in {0} ms.”, time);
}

18
2017-09-02 15:25



le chronomètre la fonctionnalité serait meilleure (précision plus élevée). Je recommande également de télécharger l’un des profils les plus populaires (DotTrace et FOURMIS sont ceux que j’ai les plus utilisés… l’essai gratuit de DotTrace est entièrement fonctionnel et ne harcele pas les autres.


16
2017-08-26 17:13



Utilisez la classe System.Diagnostics.Stopwatch.

Stopwatch sw = new Stopwatch();
sw.Start();

// Do some code.

sw.Stop();

// sw.ElapsedMilliseconds = the time your "do some code" took.

13
2017-08-26 17:13



Idem Chronomètre, c'est bien mieux.

En ce qui concerne la mesure de la performance, vous devriez également vérifier si votre "// Processus d'exécution donné" est un processus très court.

Gardez également à l'esprit que la première exécution de votre «// processus d'exécution» peut être beaucoup plus lente que les exécutions suivantes.

Je teste généralement une méthode en l'exécutant 1000 fois ou 1000000 fois dans une boucle et j'obtiens des données beaucoup plus précises que de l'exécuter une fois.


10
2017-08-30 14:24