Question

Je veux mesurer l'exécution d'un morceau de code et je me demande quelle est la meilleure méthode pour le faire est?

Option 1:

DateTime StartTime = DateTime.Now;

//Code

TimeSpan ts = DateTime.Now.Subtract(StartTime);
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");

Option 2:         en utilisant System.Diagnostics;

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

    //Code

    stopWatch.Stop();
    // Get the elapsed time as a TimeSpan value.
    TimeSpan ts = stopWatch.Elapsed;

    // Format and display the TimeSpan value.
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
    Console.WriteLine(elapsedTime, "RunTime");

Il ne suffit pas pour l'analyse comparative, est en fait une partie de l'application. Le temps de la fonction nécessaire à l'exécution est des données pertinentes. Il n'a cependant pas besoin d'être atomique ou hyper-précis.

Quelle option est préférable pour le code de production, ou que quelqu'un d'autre utiliser quelque chose de différent et peut-être mieux?

Était-ce utile?

La solution

La classe Stopwatch est spécialement conçu pour mesurer le temps écoulé et peut (si disponible sur votre matériel) fournir une bonne granularité / précision en utilisant une horloge matérielle haute fréquence sous-jacente. Donc, ce semble le meilleur choix.

Le propriété IsHighResolution peut être utilisé pour déterminer si le calendrier haute résolution est disponible. Par la documentation, cette catégorie offre une enveloppe sur le « meilleur disponible » API Win32 pour une synchronisation précise:

  

Plus précisément, le champ et Frequency   Procédé de GetTimestamp peut être utilisé dans   la place de l'API Win32 non géré   QueryPerformanceFrequency et   QueryPerformanceCounter.

Il y a fond détaillées sur les API Win32 [ici] et liés docs MSDN 2 .

  

haute résolution minuterie

     

Un compteur est un terme général utilisé dans   la programmation pour faire référence à un   variables incrémenter. certains systèmes   inclure une performance haute résolution   compteur qui fournit à haute résolution   le temps écoulé.

     

Si une performance à haute résolution   compteur existe sur le système, vous pouvez   utiliser le QueryPerformanceFrequency   fonctionner pour exprimer la fréquence, en   comptes par seconde. La valeur de la   comptage dépend processeur. Sur quelques   processeurs, par exemple, le nombre   pourrait être le taux de cycle de la   horloge processeur.

     

QueryPerformanceCounter fonction   récupère la valeur courante de la   compteur de performance à haute résolution.   En appelant cette fonction au   début et la fin d'une section de   code, une application utilise essentiellement   le compteur en haute résolution   minuteur. Par exemple, supposons que    QueryPerformanceFrequency indique   que la fréquence de la   compteur de performance à haute résolution est   50.000 comptes par seconde. Si la   appels d'application    QueryPerformanceCounter immédiatement   avant et immédiatement après la   section de code pour être programmé, la   les valeurs du compteur peut être 1500 compte   et 3500 chefs d'accusation, respectivement. Celles-ci   les valeurs indiquerait que .04 secondes   (2000 points) se sont écoulées alors que le code   exécutée.

Autres conseils

Il est pas seulement que StopWatch est plus précis, mais aussi que DateTime.Now donnera des résultats incorrects dans certaines circonstances.

Pensez à ce qui se passe pendant un temps de commutation d'été, par exemple - en utilisant DateTime.Now peut effectivement donner une négatif réponse

Ni va nuire à la performance, parce que vous dites est pas critique. StopWatch semble plus approprié - vous ne soustrayez temps de temps et non d'une date d'un autre. choses Date prend un peu plus de mémoire et de temps CPU à traiter. Il y a aussi des façons de rendre le code plus propre, si vous prévoyez qu'il réutiliser dans plusieurs endroits. using vient à Surcharge esprit. Je recherche un exemple. Ok, le code volé:

http://stevesmithblog.com/blog/great -Utilise-de-utilisant-déclaration en c /

public class ConsoleAutoStopWatch : IDisposable
{
    private readonly Stopwatch _stopWatch;

    public ConsoleAutoStopWatch()
    {
        _stopWatch = new Stopwatch();
        _stopWatch.Start();
    }

    public void Dispose()
    {
        _stopWatch.Stop();
        TimeSpan ts = _stopWatch.Elapsed;

        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                           ts.Hours, ts.Minutes, ts.Seconds,
                                           ts.Milliseconds / 10);
        Console.WriteLine(elapsedTime, "RunTime");
    }
}

private static void UsingStopWatchUsage()
{
    Console.WriteLine("ConsoleAutoStopWatch Used: ");
    using (new ConsoleAutoStopWatch())
    {
        Thread.Sleep(3000);
    }
}

Les deux seront probablement s'adapter à vos besoins très bien, mais je dirais que l'utilisation StopWatch. Pourquoi? Parce que cela signifie pour la tâche que vous faites.

Vous avez une classe qui est construit pour retourner la date / heure actuelle, qui, comme il arrive peut être utilisé pour des choses temporelles, et vous avez une classe spécialement conçu pour les choses temporelles.

Dans ce cas, les différences n'existent vraiment si vous avez besoin de précision milliseconde (Dans ce cas StopWatch est plus précis), mais comme un principe général si un outil existe spécifiquement pour la tâche que vous cherchez alors il est le meilleur à utilisation.

J'ai une petite classe pour faire ce genre de chose ad hoc. Il utilise la classe chronomètre - c # micro test perfomance .

par exemple.

var tester = new PerformanceTester(() => SomeMethod());
tester.MeasureExecTime(1000);
Console.Writeline(string.Format("Executed in {0} milliseconds", tester.AverageTime.TotalMilliseconds));

Utilisez le code ci-dessous

DateTime dExecutionTime;
dExecutionTime = DateTime.Now;
      TimeSpan span = DateTime.Now.Subtract(dExecutionTime);
                  lblExecutinTime.Text = "total time taken " +   Math.Round(span.TotalMinutes,2) + " minutes .   >>---> " + DateTime.Now.ToShortTimeString();

Je pris la réponse de Hamish simplifiée et fait un peu plus générale dans le cas où vous avez besoin de se connecter à un autre endroit:

public class AutoStopWatch : Stopwatch, IDisposable {

    public AutoStopWatch() {
        Start();
    }

    public virtual void Dispose() {
        Stop();
    }
}

 public class AutoStopWatchConsole : AutoStopWatch {

    private readonly string prefix;

    public AutoStopWatchConsole(string prefix = "") {
        this.prefix = prefix;
    }

    public override void Dispose() {
        base.Dispose();

        string format = Elapsed.Days > 0 ? "{0} days " : "";
        format += "{1:00}:{2:00}:{3:00}.{4:00}";

        Console.WriteLine(prefix + " " + format.Format(Elapsed.Days, Elapsed.Hours, Elapsed.Minutes, Elapsed.Seconds, Elapsed.Milliseconds / 10));
    }
}

private static void Usage() {

    Console.WriteLine("AutoStopWatch Used: ");
    using (var sw = new AutoStopWatch()) {
        Thread.Sleep(3000);

        Console.WriteLine(sw.Elapsed.ToString("h'h 'm'm 's's'"));
    }

    Console.WriteLine("AutoStopWatchConsole Used: ");
    using (var sw = new AutoStopWatchConsole()) {
        Thread.Sleep(3000);
    }

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