Misurazione del tempo di esecuzione del codice


120

Voglio sapere quanto tempo impiega una procedura / funzione / ordine per terminare, a scopo di test.

Questo è quello che ho fatto ma il mio metodo è sbagliato perché se la differenza di secondi è 0 non posso restituire i millisecondi trascorsi:

Si noti che il valore di sospensione è 500 ms, quindi i secondi trascorsi sono 0, quindi non possono restituire millisecondi.

    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))

Qualcuno può mostrarmi un modo migliore per farlo? Forse con un TimeSpan?

La soluzione:

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)

1
Puoi vedere la mia risposta a questa domanda:> stackoverflow.com/a/16130243/1507182 Buona fortuna
Obama

1
@Soner Se l'ho etichettato con C # è perché il codice C # è il benvenuto per me.
ElektroStudios


2
Oltre alle ovvie ragioni per utilizzare un cronometro, non dovresti mai fare alcun calcolo a DateTime.Nowcausa di problemi di ora legale e fuso orario. Si prega di leggere il mio post sul blog proprio su questo argomento
Matt Johnson-Pint

Risposte:


234

Un modo migliore sarebbe usare il cronometro , invece delle DateTimedifferenze.

Classe Stopwatch - Microsoft Docs

Fornisce una serie di metodi e proprietà che è possibile utilizzare per misurare con precisione il tempo trascorso.

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);

1
@ElektroHacker, sei il benvenuto, è più facile da usare, inoltre è più preciso di DateTime :)
Habib

1
Fare riferimento a github.com/chai-deshpande/LogExec (è disponibile anche un pacchetto NUGET nuget.org/packages/LogExec ). Questo fa esattamente le stesse cose menzionate da @ soner-gonul, ma l'uso è privo di ingombri e nasconde tutto il codice standard. Molto utile quando vuoi usarlo molto frequentemente. Utilizza anche Common.Logging in modo da poterlo integrare con il provider di registrazione preferito.
Chai

1
@ Habib puoi aiutarmi a capire perché Thread.sleep (500) è necessario? Non posso farlo saltando il sonno, questo lo renderebbe meno efficiente?
Md Sifatul Islam

8
@ Md.SifatulIslam, non è necessario usarlo Thread.Sleep, è solo lì come un codice di esempio per mostrare il ritardo .... in effetti dovresti evitare di usare Thread.Sleepovunque nel tuo codice
Habib

59

Stopwatch misura il tempo trascorso.

// 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);

Ecco un file DEMO.


può essere utilizzato per il tempo di esecuzione di ogni riga di codice? ad esempio: bindingSource.datasource = db.table; // quanto tempo ci vuole?
vaheeds il

2
@vaheeds Certo. Basta iniziare questo Stopwatchin cima a ogni riga e fermarlo dopo ogni riga. Ricorda, devi usare anche Stopwatch.Resetdopo ogni singola riga per calcolare. In base alla tua linea; dai un'occhiata ideone.com/DjR6ba
Soner Gönül

Ho fatto un piccolo trucco per togliere i millisecondi dall'immagine. in questo modo watch.Elapsed.ToString (). Split ('.') [0]
Doruk

2
@ Doruk Sì, puoi farlo o puoi usare le stringhe di formato Timespan personalizzate come il stopwatch.Elapsed.ToString(@"d\.hh\:mm\:ss")che mi sembra un modo più pulito.
Soner Gönül

1
Migliore risposta. Grazie!
Tadej

48

Puoi usare questo wrapper del cronometro:

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}");
    }
}

Uso:

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

Produzione:

Insert 10 records: 00:00:00.0617594

Per scenari avanzati, puoi utilizzare BenchmarkDotNet o Benchmark.It o NBench


3
Grazie, migliore risposta finora
pixel

2
Grazie, stavo cercando tale in modo centralizzato. Ho fatto questa strategia anche con ActionFilter.
ಅನಿಲ್

13

Se usi la classe Stopwatch, puoi usare il metodo .StartNew () per reimpostare l'orologio a 0. Quindi non devi chiamare .Reset () seguito da .Start (). Potrebbe tornare utile.


4

Stopwatch è progettato per questo scopo ed è uno dei modi migliori per misurare il tempo di esecuzione in .NET.

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

Non utilizzare DateTimes per misurare il tempo di esecuzione in .NET.


3

Se stai cercando la quantità di tempo che il thread associato ha impiegato per eseguire il codice all'interno dell'applicazione.
Puoi usare ProcessThread.UserProcessorTimeProperty che puoi ottenere sotto lo System.Diagnosticsspazio dei nomi.

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

Nota: se si utilizzano più thread, è possibile calcolare il tempo di ogni thread individualmente e sommarlo per calcolare la durata totale.


0

Non sono riuscito a vedere una versione vb.net di come si potrebbe utilizzare la classe stopwatch, quindi ho fornito un esempio di seguito.

        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)

Spero che questo aiuti chiunque sia arrivato a questa domanda cercando vb.net.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.