Mengukur waktu eksekusi kode

120

Saya ingin tahu berapa banyak waktu yang dibutuhkan untuk menyelesaikan suatu prosedur / fungsi / perintah, untuk tujuan pengujian.

Ini yang saya lakukan tetapi metode saya salah karena jika selisih detik 0 tidak dapat mengembalikan milidetik yang telah berlalu:

Perhatikan nilai sleep adalah 500 ms sehingga detik yang berlalu adalah 0 maka tidak dapat mengembalikan milidetik.

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

Dapatkah seseorang menunjukkan kepada saya cara yang lebih baik untuk melakukan ini? Mungkin dengan TimeSpan?

Solusinya:

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
sumber
1
Anda dapat melihat jawaban saya untuk pertanyaan ini:> stackoverflow.com/a/16130243/1507182 Semoga beruntung
Obama
1
@Soner Jika saya menandainya dengan C # adalah karena kode C # diterima untuk saya.
ElektroStudios
2
kemungkinan duplikat dari Find Execution time of a Method
Jesse
2
Selain alasan yang jelas untuk menggunakan stopwatch, Anda tidak boleh melakukan matematika apa pun DateTime.Nowkarena masalah Daylight Savings dan Time Zone. Silakan baca posting blog saya tentang subjek ini
Matt Johnson-Pint

Jawaban:

234

Cara yang lebih baik adalah menggunakan Stopwatch , daripada menggunakan DateTimeperbedaan.

Kelas Stopwatch - Microsoft Docs

Menyediakan sekumpulan metode dan properti yang dapat Anda gunakan untuk mengukur waktu yang telah berlalu secara akurat.

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
sumber
1
@ElektroHacker, sama-sama, lebih mudah digunakan, plus lebih akurat daripada DateTime :)
Habib
1
Silakan lihat github.com/chai-deshpande/LogExec (paket NUGET juga tersedia nuget.org/packages/LogExec ). Ini melakukan hal yang sama persis dengan yang disebutkan @ soner-gonul - tetapi, penggunaannya bebas dari kekacauan dan menyembunyikan semua kode boilerplate. Sangat membantu jika Anda ingin sering menggunakannya. Ia juga menggunakan Common.Logging sehingga Anda bisa berintegrasi dengan penyedia logging pilihan Anda.
Chai
1
@Habib dapatkah Anda membantu saya untuk memahami mengapa Thread.sleep (500) diperlukan? Tidak bisakah saya melakukannya dengan melewatkan waktu tidur, apakah itu akan membuatnya kurang efisien?
Md Sifatul Islam
8
@ Md.SifatulIslam, tidak perlu menggunakan Thread.Sleep, hanya ada sebagai contoh kode untuk menunjukkan penundaan .... sebenarnya Anda harus menghindari penggunaan Thread.Sleepdi mana saja dalam kode Anda
Habib
59

Stopwatch mengukur waktu yang telah berlalu.

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

Ini a DEMO.

Soner Gönül
sumber
dapatkah itu digunakan untuk waktu eksekusi setiap baris kode? misalnya: bindingSource.datasource = db.table; // berapa lama?
vaheeds
2
@vaheed Tentu. Mulailah ini Stopwatchdi atas setiap baris Anda dan hentikan setelah setiap baris Anda. Ingat, Anda perlu menggunakan juga Stopwatch.Resetsetelah setiap baris untuk menghitung. Berdasarkan garis Anda; lihat ideone.com/DjR6ba
Soner Gönül
saya melakukan sedikit trik untuk mengeluarkan milidetik dari gambar. dengan cara ini perhatikan.Elapsed.ToString (). Split ('.') [0]
Doruk
2
@Doruk Ya, Anda dapat melakukannya atau Anda dapat menggunakan String Format Jangka Waktu Kustom seperti stopwatch.Elapsed.ToString(@"d\.hh\:mm\:ss")yang menurut saya cara yang lebih bersih.
Soner Gönül
1
Jawaban Terbaik. Terima kasih!
Tadej
48

Anda dapat menggunakan pembungkus Stopwatch ini:

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

Pemakaian:

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

Keluaran:

Insert 10 records: 00:00:00.0617594

Untuk skenario lanjutan, Anda bisa menggunakan BenchmarkDotNet atau Benchmark.It atau NBench

Alex Erygin
sumber
3
Terima kasih, jawaban terbaik sejauh ini
piksel
2
Terima kasih, Sedang mencari seperti itu secara terpusat. Telah melakukan strategi ini dengan ActionFilter juga.
ಅನಿಲ್
13

Jika Anda menggunakan kelas Stopwatch, Anda dapat menggunakan metode .StartNew () untuk menyetel ulang jam tangan ke 0. Jadi, Anda tidak perlu memanggil .Reset () diikuti oleh .Start (). Mungkin berguna.

ohgodnotanotherone
sumber
4

Stopwatch dirancang untuk tujuan ini dan merupakan salah satu cara terbaik untuk mengukur eksekusi waktu di .NET.

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

Jangan gunakan DateTimes untuk mengukur eksekusi waktu di .NET.

Sam
sumber
3

Jika Anda mencari jumlah waktu yang dihabiskan utas terkait untuk menjalankan kode di dalam aplikasi.
Anda dapat menggunakan ProcessThread.UserProcessorTimeProperti yang bisa Anda dapatkan di 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

Catatan: Jika Anda menggunakan multi utas, Anda dapat menghitung waktu setiap utas satu per satu dan menjumlahkannya untuk menghitung durasi total.

Shailesh Prajapati
sumber
0

Saya tidak dapat melihat versi vb.net tentang bagaimana seseorang dapat menggunakan Stopwatch Class jadi saya telah memberikan contoh di bawah ini.

        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)

Saya harap ini membantu siapa saja yang sampai pada pertanyaan ini mencari vb.net.

kayu gergaji
sumber