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.