Kod yürütme süresini ölçme


120

Test amacıyla bir prosedürün / işlevin / siparişin ne kadar sürede tamamlandığını bilmek istiyorum.

Yaptığım buydu ama yöntemim yanlış çünkü saniye farkı 0 ise geçen milisaniyeleri döndüremez:

Uyku değerinin 500 ms olduğuna dikkat edin, bu nedenle geçen saniye 0 olduğundan milisaniye döndüremez.

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

Biri bana bunu yapmanın daha iyi bir yolunu gösterebilir mi? Belki bir ile TimeSpan?

Çözüm:

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
Bu soruya cevabımı görebilirsiniz:> stackoverflow.com/a/16130243/1507182 İyi şanslar
Obama

1
@Soner C # ile etiketlediysem, C # kodunun benim için hoş karşılanmasıdır.
ElektroStudios


2
Kronometre kullanmanın bariz nedenlerinin yanı sıra, DateTime.NowYaz Saati ve Saat Dilimi sorunları nedeniyle asla matematik yapmamalısınız . Lütfen bu konudaki blog yazımı
Matt Johnson-Pint

Yanıtlar:


234

Farklılıklar yerine Kronometreyi kullanmak daha iyi bir yol olacaktır DateTime.

Kronometre Sınıfı - Microsoft Docs

Geçen zamanı doğru bir şekilde ölçmek için kullanabileceğiniz bir dizi yöntem ve özellik sağlar.

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, hoş geldiniz, kullanımı daha kolay, ayrıca DateTime'dan daha doğru :)
Habib

1
Lütfen github.com/chai-deshpande/LogExec adresine bakın (bir NUGET paketi ayrıca nuget.org/packages/LogExec mevcuttur ). Bu, @ soner-gonul'un bahsettiği şeylerin aynısını yapar - ancak kullanım dağınıklık içermez ve tüm standart kodu gizler. Çok sık kullanmak istediğinizde çok yardımcı oluyor. Ayrıca, tercih ettiğiniz günlük kaydı sağlayıcınızla entegre olabilmeniz için Common.Logging'i kullanır.
Chai

1
@Habib, Thread.sleep (500) 'ün neden gerekli olduğunu anlamama yardım eder misin? Uykuyu atlayarak yapamaz mıyım, bu onu daha az verimli yapar mı?
Md Sifatul Islam

8
@ Md.SifatulIslam, kullanmaya gerek yok Thread.Sleep, sadece gecikmeyi göstermek için örnek bir kod var .... aslında Thread.Sleepkodunuzun herhangi bir yerini kullanmaktan kaçınmalısınız
Habib

60

Stopwatch geçen zamanı ölçer.

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

İşte bir DEMO.


her kod satırının yürütme süresi için kullanılabilir mi? örneğin: bindingSource.datasource = db.table; // ne kadar uzun sürer?
vaheeds

2
@vaheeds Tabii. Bunu Stopwatchher satırınızın üstünde başlatın ve her satırınızdan sonra durdurun. Unutmayın, Stopwatch.Resethesaplamak için her satırdan sonra da kullanmanız gerekir . Hattınıza göre; bir göz atın ideone.com/DjR6ba
Soner Gönül

Milisaniyeleri görünmez hale getirmek için küçük bir numara yaptım. bu şekilde watch.Elapsed.ToString (). Split ('.') [0]
Doruk

2
@Doruk Evet, bunu yapabilirsin veya benim için daha temiz bir yol gibi görünen Özel Zaman Aralığı Biçimi Dizelerini kullanabilirsin stopwatch.Elapsed.ToString(@"d\.hh\:mm\:ss").
Soner Gönül

1
En iyi cevap. Teşekkürler!
Tadej

48

Bu Kronometre sarmalayıcısını kullanabilirsiniz:

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

Kullanımı:

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

Çıktı:

Insert 10 records: 00:00:00.0617594

Gelişmiş senaryolar için BenchmarkDotNet veya Benchmark kullanabilirsiniz. It veya NBench


3
Teşekkürler, şimdiye kadarki en iyi yanıt
pixel

2
Teşekkürler, merkezi bir şekilde arıyordum. Bu stratejiyi ActionFilter ile de yaptınız.
ಅನಿಲ್

13

Kronometre sınıfını kullanırsanız, saati 0'a sıfırlamak için .StartNew () yöntemini kullanabilirsiniz. Böylece .Reset () ve ardından .Start () çağrısı yapmanız gerekmez . İşe yarayabilir.


4

Kronometre bu amaç için tasarlanmıştır ve .NET'te zaman yürütmeyi ölçmenin en iyi yollarından biridir.

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

.NET'te zaman yürütmeyi ölçmek için Tarih Saatlerini kullanmayın.


3

İlişkili iş parçacığının uygulama içinde kod çalıştırmak için harcadığı süreyi arıyorsanız.
İsim alanı ProcessThread.UserProcessorTimealtında alabileceğiniz Property kullanabilirsiniz System.Diagnostics.

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

Not: Çoklu iş parçacığı kullanıyorsanız, her iş parçacığının süresini ayrı ayrı hesaplayabilir ve toplam süreyi hesaplamak için toplayabilirsiniz.


0

Kronometre Sınıfının nasıl kullanılacağına dair vb.net versiyonunu göremedim, bu yüzden aşağıda bir örnek verdim.

        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)

Umarım bu, vb.net'i arayan bu soruya gelen herkese yardımcı olur.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.