Mesurer le temps d'exécution du code

120

Je veux savoir combien de temps une procédure / fonction / commande prend pour terminer, à des fins de test.

C'est ce que j'ai fait mais ma méthode est fausse car si la différence de secondes est de 0, je ne peux pas retourner les millisecondes écoulées:

Notez que la valeur de veille est de 500 ms, donc les secondes écoulées sont égales à 0, alors il ne peut pas retourner les millisecondes.

    Dim Execution_Start As System.DateTime = System.DateTime.Now
    Threading.Thread.Sleep(500)

    Dim Execution_End As System.DateTime = System.DateTime.Now
    MsgBox(String.Format("H:{0} M:{1} S:{2} MS:{3}", _
    DateDiff(DateInterval.Hour, Execution_Start, Execution_End), _
    DateDiff(DateInterval.Minute, Execution_Start, Execution_End), _
    DateDiff(DateInterval.Second, Execution_Start, Execution_End), _
    DateDiff(DateInterval.Second, Execution_Start, Execution_End) * 60))

Quelqu'un peut-il me montrer une meilleure façon de faire cela? Peut-être avec un TimeSpan?

La solution:

Dim Execution_Start As New Stopwatch
Execution_Start.Start()

Threading.Thread.Sleep(500)

MessageBox.Show("H:" & Execution_Start.Elapsed.Hours & vbNewLine & _
       "M:" & Execution_Start.Elapsed.Minutes & vbNewLine & _
       "S:" & Execution_Start.Elapsed.Seconds & vbNewLine & _
       "MS:" & Execution_Start.Elapsed.Milliseconds & vbNewLine, _
       "Code execution time", MessageBoxButtons.OK, MessageBoxIcon.Information)
ElektroStudios
la source
1
Vous pouvez voir ma réponse sur cette question:> stackoverflow.com/a/16130243/1507182 Bonne chance
Obama
1
@Soner Si je l'ai tagué avec C #, c'est parce que le code C # est le bienvenu pour moi.
ElektroStudios
2
duplication possible du temps d'exécution
Jesse
2
Outre les raisons évidentes d'utiliser un chronomètre, vous ne devriez jamais faire de calculs avec en DateTime.Nowraison de problèmes d'heure d'été et de fuseau horaire. S'il vous plaît lire mon article de blog sur ce sujet même
Matt Johnson-Pint

Réponses:

234

Une meilleure façon serait d'utiliser Chronomètre , au lieu des DateTimedifférences.

Cours de chronomètre - Microsoft Docs

Fournit un ensemble de méthodes et de propriétés que vous pouvez utiliser pour mesurer avec précision le temps écoulé.

Stopwatch stopwatch = Stopwatch.StartNew(); //creates and start the instance of Stopwatch
//your sample code
System.Threading.Thread.Sleep(500);
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Habib
la source
1
@ElektroHacker, vous êtes les bienvenus, c'est plus facile à utiliser, plus il est plus précis que DateTime :)
Habib
1
Veuillez vous référer à github.com/chai-deshpande/LogExec (un package NUGET est également disponible sur nuget.org/packages/LogExec ). Cela fait exactement les mêmes choses que @ soner-gonul a mentionnées - mais l'utilisation est sans encombrement et masque tout le code standard. Très utile lorsque vous souhaitez l'utiliser très fréquemment. Il utilise également Common.Logging afin que vous puissiez l'intégrer à votre fournisseur de journalisation préféré.
Chai
1
@Habib pouvez-vous s'il vous plaît m'aider à comprendre pourquoi Thread.sleep (500) est nécessaire? Je ne peux pas le faire en sautant le sommeil, cela le rendrait-il moins efficace?
Md Sifatul Islam
8
@ Md.SifatulIslam, il n'y a pas besoin de l'utiliser Thread.Sleep, c'est juste là comme exemple de code pour montrer le retard .... en fait, vous devriez éviter d'utiliser Thread.Sleepn'importe où dans votre code
Habib
60

Stopwatch mesure le temps écoulé.

// Create new stopwatch
Stopwatch stopwatch = new Stopwatch();

// Begin timing
stopwatch.Start();

Threading.Thread.Sleep(500)

// Stop timing
stopwatch.Stop();

Console.WriteLine("Time elapsed: {0}", stopwatch.Elapsed);

Voici un DEMO.

Soner Gönül
la source
peut-il être utilisé pour le temps d'exécution de chaque ligne de code? par exemple: bindingSource.datasource = db.table; // combien de temps cela prend-il?
vaheeds
2
@vaheeds Bien sûr. Commencez simplement ceci Stopwatchau-dessus de chaque ligne et arrêtez-le après chaque ligne. N'oubliez pas que vous devez également utiliser Stopwatch.Resetaprès chaque ligne pour calculer. Basé sur votre ligne; jetez un oeil ideone.com/DjR6ba
Soner Gönül
J'ai fait un petit truc dessus pour éliminer les millisecondes. de cette façon watch.Elapsed.ToString (). Split ('.') [0]
Doruk
2
@Doruk Ouais, vous pouvez le faire ou vous pouvez utiliser des chaînes de format Timespan personnalisées comme stopwatch.Elapsed.ToString(@"d\.hh\:mm\:ss")ce qui me semble plus propre.
Soner Gönül
1
Meilleure réponse. Merci!
Tadej
48

Vous pouvez utiliser ce wrapper Chronomètre:

public class Benchmark : IDisposable 
{
    private readonly Stopwatch timer = new Stopwatch();
    private readonly string benchmarkName;

    public Benchmark(string benchmarkName)
    {
        this.benchmarkName = benchmarkName;
        timer.Start();
    }

    public void Dispose() 
    {
        timer.Stop();
        Console.WriteLine($"{benchmarkName} {timer.Elapsed}");
    }
}

Usage:

using (var bench = new Benchmark($"Insert {n} records:"))
{
    ... your code here
}

Production:

Insert 10 records: 00:00:00.0617594

Pour les scénarios avancés, vous pouvez utiliser BenchmarkDotNet ou Benchmark.It ou NBench

Alex Erygin
la source
3
Merci, meilleure réponse à ce jour
pixel
2
Merci, recherchait un tel de manière centralisée. J'ai également fait cette stratégie avec ActionFilter.
ಅನಿಲ್
13

Si vous utilisez la classe Stopwatch, vous pouvez utiliser la méthode .StartNew () pour réinitialiser la montre à 0. Vous n'avez donc pas besoin d'appeler .Reset () suivi de .Start (). Cela pourrait être utile.

ohgodnotanotherone
la source
4

Le chronomètre est conçu à cet effet et constitue l'un des meilleurs moyens de mesurer l'exécution du temps dans .NET.

var watch = System.Diagnostics.Stopwatch.StartNew();
/* the code that you want to measure comes here */
watch.Stop();
var elapsedMs = watch.ElapsedMilliseconds;

N'utilisez pas DateTimes pour mesurer le temps d'exécution dans .NET.

Sam
la source
3

Si vous recherchez le temps que le thread associé a passé à exécuter du code dans l'application.
Vous pouvez utiliser ProcessThread.UserProcessorTimeProperty que vous pouvez obtenir sous l' System.Diagnosticsespace de noms.

TimeSpan startTime= Process.GetCurrentProcess().Threads[i].UserProcessorTime; // i being your thread number, make it 0 for main
//Write your function here
TimeSpan duration = Process.GetCurrentProcess().Threads[i].UserProcessorTime.Subtract(startTime);

Console.WriteLine($"Time caluclated by CurrentProcess method: {duration.TotalSeconds}"); // This syntax works only with C# 6.0 and above

Remarque: Si vous utilisez plusieurs threads, vous pouvez calculer le temps de chaque thread individuellement et le additionner pour calculer la durée totale.

Shailesh Prajapati
la source
0

Je ne pouvais pas voir une version vb.net de la façon dont on pourrait utiliser la classe chronomètre, j'ai donc fourni un exemple ci-dessous.

        Dim Stopwatch As New Stopwatch

        Stopwatch.Start()
                    ''// Test Code
        Stopwatch.Stop()
        Console.WriteLine(Stopwatch.Elapsed.ToString)

        Stopwatch.Restart()            
                   ''// Test Again

        Stopwatch.Stop()
        Console.WriteLine(Stopwatch.Elapsed.ToString)

J'espère que cela aidera quiconque est arrivé à cette question à la recherche de vb.net.

scie
la source