Est De Type DateTime.Maintenant, la meilleure façon de mesurer un rendement de la fonction?

StackOverflow https://stackoverflow.com/questions/28637

Question

J'ai besoin de trouver un goulot d'étranglement et le besoin de précision que possible de mesurer le temps.

Est l'extrait de code suivant, la meilleure façon de mesurer la performance?

DateTime startTime = DateTime.Now;

// Some execution process

DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
Était-ce utile?

La solution

Non, il n'est pas.L'utilisation de la Chronomètre (en 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 haute précision des temporisateurs.

Il vaut la peine de mentionner que DateTime.Now souvent est un peu plus lent que DateTime.UtcNow en raison du travail qui doit être fait avec les fuseaux horaires, D'heure d'été et tel.

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

Anecdote intéressante:Le chronomètre revient sur DateTime.UtcNow si votre matériel ne supporte pas l'à haute fréquence compteur.Vous pouvez vérifier pour voir si le Chronomètre utilise du matériel afin d'atteindre une haute précision en regardant le champ statique Le chronomètre.IsHighResolution.

Autres conseils

Si vous voulez quelque chose de rapide et sale je suggère d'utiliser le Chronomètre, au lieu d'un plus grand degré de précision.

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

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

Alternativement, si vous besoin de quelque chose d'un peu plus sophistiqué que vous devriez probablement envisager l'aide d'un 3ème partie profiler comme Les FOURMIS.

Cet article dit que tout d'abord vous avez besoin de comparer les trois solutions, Stopwatch, DateTime.Now ET DateTime.UtcNow.

Il montre également que, dans certains cas (lorsque le compteur de performance n'existe pas) Chronomètre est à l'aide de DateTime.UtcNow + traitement supplémentaire.De ce fait, il est évident que, dans ce cas DateTime.UtcNow est la meilleure option (parce que d'autres l'utilisent + traitement)

Cependant, comme il s'avère, le compteur existe presque toujours - voir Explication sur la haute résolution de compteur de performances et de son existence liés à l' .NET Chronomètre?.

Voici une représentation graphique de la performance.Remarquez comment faible coût de performances UtcNow a par rapport aux alternatives:

Enter image description here

L'axe des X est l'exemple de la taille des données, et l'axe Y est la durée relative de l'exemple.

Une chose Stopwatch le mieux est qu'il fournit une résolution plus élevée des mesures de temps.Un autre est son plus OO nature.Cependant, la création d'un wrapper autour OO UtcNow ne peut pas être dur.

Il est utile de pousser votre banc de code dans une classe utilitaire/méthode.L' StopWatch la classe n'a pas besoin d'être Disposed ou Stopped en cas d'erreur.Ainsi, le code le plus simple pour le 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 méthode d'extension de la version

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

Et l'exemple de code d'appel

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

L' chronomètre la fonctionnalité serait mieux (plus de précision).Je recommande aussi juste de télécharger l'un des populaires profileurs, si (DotTrace et Les FOURMIS sont ceux que j'ai le plus utilisé...la version d'essai gratuite pour DotTrace est entièrement fonctionnel et n'est pas bourrin comme certains des autres).

Utiliser le Système.Diagnostics.Chronomètre de classe.

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

// Do some code.

sw.Stop();

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

Idem Chronomètre, c'est mieux.

Concernant la mesure de la performance, vous devriez également vérifier si votre "// Certains Processus d'Exécution" est un très court processus.

Aussi garder à l'esprit que la première exécution de votre "// Certains Processus d'Exécution" pourrait être beaucoup plus lent que les exécutions suivantes.

En général, je test une méthode en l'exécutant 1000 fois ou 1000000 fois dans une boucle et je reçois beaucoup de données plus précises que de courir à la fois.

Ce sont tous d'excellents moyens de mesurer le temps, mais qui n'est qu'une façon indirecte de trouver un goulet d'étranglement(s).

Le moyen le plus direct pour trouver un bottneck dans un thread est pour le remettre en marche, et alors qu'il est en train de faire tout ce qui peut vous attendre, d'y mettre un terme avec une pause ou de casser la clé.Faites-le plusieurs fois.Si le goulot d'étranglement prend X% du temps, X% est la probabilité que vous l'attraper dans l'acte sur chaque cliché.

Voici une explication plus complète de comment et pourquoi il fonctionne

@Sean Chambres

Pour info, le .NET classe Timer n'est pas pour le diagnostic, il génère des événements à un intervalle prédéfini, comme ceci (à partir de MSDN):

System.Timers.Timer aTimer;
public static void Main()
{
    // Create a timer with a ten second interval.
    aTimer = new System.Timers.Timer(10000);

    // Hook up the Elapsed event for the timer.
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer.Interval = 2000;
    aTimer.Enabled = true;

    Console.WriteLine("Press the Enter key to exit the program.");
    Console.ReadLine();
}

// Specify what you want to happen when the Elapsed event is 
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}

Donc, ce n'est pas vraiment vous aider à savoir combien de temps cela a pris, juste une certaine quantité de temps a passé.

La minuterie est également exposée comme un contrôle dans le Système.De Windows.Les formes...vous pouvez le trouver dans votre concepteur de boîte à outils dans VS05/VS08

C'est la façon correcte:

using System;
using System.Diagnostics;

class Program
{
    public static void Main()
    {
        Stopwatch stopWatch = Stopwatch.StartNew();

            // some other code

        stopWatch.Stop();

        // this not correct to get full timer resolution
        Console.WriteLine("{0} ms", stopWatch.ElapsedMilliseconds);

        // Correct way to get accurate high precision timing
        Console.WriteLine("{0} ms", stopWatch.Elapsed.TotalMilliseconds);
    }
}

Pour plus d'informations, allez à travers Utilisation du Chronomètre au lieu de DataTime pour obtenir de la précision du compteur de performance.

Visual Studio Team System a certaines fonctionnalités qui peuvent aider avec ce problème.Essentiellement, vous pouvez écrire des tests unitaires et le mélange de différents scénarios à l'encontre de votre logiciel dans le cadre d'un stress ou de test de charge.Cela peut aider à identifier les zones de code que un impact sur votre performance des applications les plus.

Microsoft " Modèles et Pratiques de groupe a une certaine orientation dans Visual Studio Team System Test De Performance D'Orientation.

Je viens de trouver un post dans Vance Morrison blog sur un CodeTimer classe il a écrit qui rend l'utilisation de StopWatch facile et ne bien des choses sur le côté.

J'ai fait très peu de ce genre de performance vérification (j'ai tendance à pense juste que "c'est lent, le rendre plus rapide") et j'ai donc presque toujours disparu avec cette.

Google fait apparaître un grand nombre de ressources/articles pour la performance de la vérification.

De nombreux mention utilisant pinvoke pour obtenir de l'information sur le rendement.Beaucoup de documents que je n'étudier qu'vraiment mentionner l'aide de l'analyseur de performances..

Edit:

Vu les pourparlers de Chronomètre..Nice!J'ai appris quelque chose :)

Cela ressemble à un bon article

La façon dont j'utilise dans mes programmes est d'utiliser le Chronomètre de la classe, comme indiqué ici.

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


// Critical lines of code

long elapsedMs = sw.Elapsed.TotalMilliseconds;

Ce n'est pas assez professionnel:

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

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

Plus fiable, la version est:

PerformWork();

int repeat = 1000;

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < repeat; i++)
{
   PerformWork();
}

sw.Stop();

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

Dans mon code, je vais ajouter de la GC.Appel en pcv de changer tas managé à un état connu, et ajouter le Sommeil d'appel de sorte que les différents intervalles de code peut être facilement séparé en ETW profil.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top