Jak precyzyjnie zmierzyć czas z poziomu .NET (C#)?

Witam,

Potrzebuję jak najbardziej precyzyjnie (z rozdzielczością mikrosekund) zmierzyć czas w systemie Windows. Potrzebuję to zrobić w aplikacji na platformie .NET (pisanej w C#).

Zależy mi, by to było jak najdokładniejsze, by można było zmierzyć czas wykonywania pewnego (krótkiego) kodu.

Jaki jest najlepszy sposób?

pozdrawiam,

Maciek

http://maciej-progtech.blogspot.com/

5 miesięcy, 4 tygodnie temu | edytowane przez: MaciejZbrzezny 77010

  • Możesz użyć do tego stopera (klasa StopWatch). Jest to dedykowana klasa do takich potrzeb dostępna w System.Diagnostics. Jeżeli chcesz uzyskać najdokładniejsze wyniki to użyj właściwość Ticks, która zwraca czas z dokładnością do 100 nanosekund: Przykład użycia:

        System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
        System.Threading.Thread.Sleep(1234);
        sw.Stop();
        MessageBox.Show(String.Format("Minęło {0} nanosekund", sw.Elapsed.Ticks * 100));
    

    Zasadniczo Stopwatch realizuje kod, który można opisać tak:

        DateTime p = DateTime.Now;
        System.Threading.Thread.Sleep(1234);
        DateTime k = DateTime.Now;
        TimeSpan Roznica = k - p;
        MessageBox.Show(String.Format("Minęło {0} nanosekund", Roznica.Ticks * 100));
    

    Jak mierzyć bardzo małe czasy?

    Jeżeli czasy są tak małe że masz problemy z ich zmierzeniem, to warto rozważyć wielokrotne odpalenie testu i mierzenie czasu całościowego i podzielenie na liczbę prób. Dzięki temu wyniki będą uśrednione i uniezależnione od chwilowych wahań wydajności komputera i dokładniejsze przez to. Czyli:

    • zmierzenie czasu 100 prób
    • podzielenie uzyskanego czasu przez 100
    • wynik będzie uśredniony i uniezależniony od wachań w wydajności systemu

  • System.Diagnostics.Stopwatch również nieźle się sprawdzi w tym zadaniu. Przykładowe zastosowanie mierzące czas i predkość pobierania pliku znajduje się poniżej.

        public static void Main(string[] args)
        {
            const string tempfile = "tempfile.tmp";
            System.Net.WebClient webClient = new System.Net.WebClient();
    
            Console.WriteLine("Downloading file....");
    
            System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
            webClient.DownloadFile("http://www.google.pl/intl/en_com/images/logo_plain.png", tempfile);
    
            sw.Stop();
    
            FileInfo fileInfo = new FileInfo(tempfile);
            long speed = fileInfo.Length / sw.Elapsed.Milliseconds;
    
            Console.WriteLine("Download duration: {0}", sw.Elapsed);
            Console.WriteLine("File size: {0}", fileInfo.Length.ToString("N0"));
            Console.WriteLine("Speed: {0} ", (speed*1000)/1024);
    
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
    
        }
    

  • Pobierzesz aktualną datę, to było coś w rodzaju DateTime.Current. i tutaj jest wartość w milisekundach jak dobrze pamiętam, chyba że potrzebujesz coś naprawdę dokładnego - bo nie jestem pewien czy to nie ma pewnyhc minusów (dokładność)

    no i znalazłem coś dokładniejszego - to akurat wiem już z C++ ;-)
    LINK

  • W zasadzie wszystko zostało powiedziane, a prawidłowo odpowiedział Inquistor - do tego służy klasa Stopwatch. Inne rozwiązania też są OK, ale to jak wbijanie gwoździ za pomocą buta. Niby się da, ale po co?

    Dodam tylko od siebie, że jeżeli rozdzielczość pomiaru tej klasy jest zbyt mała, to po prostu puść swój kod w pętli - np. 100 lub 1000 razy - i mierz ile czasu będzie trwało wykonanie tylu iteracji. Na koniec podziel wynik przez liczbę iteracji i będziesz miał dużo dokładniejsze oszacowanie.

Zaloguj się, aby dodać swoją odpowiedź