Medindo o tempo de execução do código

120

Quero saber quanto tempo leva para terminar um procedimento / função / pedido, para fins de teste.

Fiz isso, mas meu método está errado porque se a diferença de segundos for 0 não pode retornar os milissegundos decorridos:

Observe que o valor do sono é 500 ms, portanto, os segundos decorridos são 0, então ele não pode retornar milissegundos.

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

Alguém pode me mostrar uma maneira melhor de fazer isso? Talvez com um TimeSpan?

A solução:

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
fonte
1
Você pode ver minha resposta para esta pergunta:> stackoverflow.com/a/16130243/1507182 Boa sorte
Obama
1
@Soner Se eu o marquei com C # é porque o código C # é bem-vindo para mim.
ElektroStudios
2
possível duplicata de Find Execution time of a Method
Jesse
2
Além das razões óbvias para usar um cronômetro, você nunca deve fazer nenhuma matemática DateTime.Nowdevido a problemas de horário de verão e fuso horário. Por favor, leia minha postagem no blog sobre este assunto
Matt Johnson-Pint

Respostas:

234

A melhor maneira seria usar o cronômetro , em vez de DateTimediferenças.

Aula do cronômetro - Microsoft Docs

Fornece um conjunto de métodos e propriedades que você pode usar para medir com precisão o tempo decorrido.

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
fonte
1
@ElektroHacker, de nada, é mais fácil de usar, além de mais preciso que DateTime :)
Habib
1
Consulte github.com/chai-deshpande/LogExec (um pacote NUGET também está disponível nuget.org/packages/LogExec ). Isso faz exatamente as mesmas coisas que @ soner-gonul mencionou - mas, o uso é desordenado e oculta todo o código clichê. Muito útil quando você deseja usá-lo com muita frequência. Ele também usa Common.Logging para que você possa integrar com seu provedor de registro preferido.
Chai de
1
@Habib, você pode me ajudar a entender por que Thread.sleep (500) é necessário? Não posso fazer isso pulando o sono, isso o tornaria menos eficiente?
Md Sifatul Islam
8
@ Md.SifatulIslam, não há necessidade de usar Thread.Sleep, apenas como um código de amostra para mostrar o atraso .... na verdade, você deve evitar o usoThread.Sleep qualquer lugar em seu código
Habib
59

Stopwatch mede o tempo decorrido.

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

Aqui está um DEMO.

Soner Gönül
fonte
pode ser usado para o tempo de execução de cada linha de código? por exemplo: bindingSource.datasource = db.table; // quanto demora?
vaheeds
2
@vaheeds Claro. Basta começar Stopwatchno topo de cada linha e pará-lo após cada linha. Lembre-se de que você precisa usar também Stopwatch.Reseton após cada linha para calcular. Com base em sua linha; dê uma olhada em ideone.com/DjR6ba
Soner Gönül
fiz um pequeno truque para tirar os milissegundos da imagem. desta forma watch.Elapsed.ToString (). Split ('.') [0]
Doruk
2
@Doruk Sim, você pode fazer isso ou você pode usar personalizado timeSpan cadeias de formato como stopwatch.Elapsed.ToString(@"d\.hh\:mm\:ss")o que parece uma maneira mais limpa para mim.
Soner Gönül
1
Melhor resposta. Obrigado!
Tadej de
48

Você pode usar este invólucro do cronômetro:

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
}

Resultado:

Insert 10 records: 00:00:00.0617594

Para cenários avançados, você pode usar BenchmarkDotNet ou Benchmark.It ou NBench

Alex Erygin
fonte
3
Obrigado, melhor resposta até agora
pixel
2
Obrigado, Estava procurando de forma centralizada. Fiz essa estratégia com ActionFilter também.
ಅನಿಲ್
13

Se você usar a classe Stopwatch, poderá usar o método .StartNew () para redefinir o relógio para 0. Assim, você não precisa chamar .Reset () seguido de .Start (). Pode ser útil.

ohgodnotanotherone
fonte
4

O cronômetro foi projetado para esse fim e é uma das melhores formas de medir o tempo de execução em .NET.

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

Não use DateTimes para medir o tempo de execução no .NET.

Sam
fonte
3

Se você estiver procurando por quanto tempo o thread associado gastou executando o código dentro do aplicativo.
Você pode usar a ProcessThread.UserProcessorTimepropriedade que pode obter no System.Diagnosticsnamespace.

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 você estiver usando multi threads, você pode calcular o tempo de cada thread individualmente e somar para calcular a duração total.

Shailesh Prajapati
fonte
0

Não consegui ver uma versão vb.net de como alguém poderia usar a classe do cronômetro, então forneci um exemplo abaixo.

        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)

Espero que isso ajude qualquer pessoa que tenha chegado a esta questão procurando por vb.net.

serra
fonte