To DateTime.Teraz najlepszy sposób pomiaru wydajności funkcji? [zamknięte]

Zamknięte . To pytanie jest oparte na opinii . Obecnie nie przyjmuje odpowiedzi.

Chcesz poprawić to pytanie? Zaktualizuj pytanie, aby mogło być odpowiedź z faktami i cytatami przez edytując ten post .

Zamknięte 4 miesiące temu .

Popraw to pytanie

Muszę znaleźć wąskie gardło i muszę dokładnie jak to możliwe zmierzyć czas.

Czy poniższy fragment kodu jest najlepszym sposobem pomiaru wydajności?

DateTime startTime = DateTime.Now;

// Some execution process

DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
Author: Peter Mortensen, 2008-08-26

16 answers

Nie, Nie jest. Użyj stopera (W System.Diagnostics)

Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

Stoper automatycznie sprawdza istnienie precyzyjnych timerów.

Warto wspomnieć, że DateTime.Now często jest nieco wolniejszy niż DateTime.UtcNow ze względu na pracę, która musi być wykonana w strefach czasowych, DST i tym podobne.

DateTime.UtcNow zazwyczaj ma rozdzielczość 15 ms. Zobacz John Chapman ' s blog post about DateTime.Now precision, aby uzyskać świetne podsumowanie.

Ciekawe ciekawostki: The stoper włącza się ponownie DateTime.UtcNow, Jeśli twój sprzęt nie obsługuje licznika wysokiej częstotliwości. Możesz sprawdzić, czy Stoper używa sprzętu do osiągnięcia wysokiej precyzji, patrząc na pole statyczne stopera.IsHighResolution .

 655
Author: Markus Olsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-21 20:33:12

Jeśli chcesz czegoś szybkiego i brudnego, sugerowałbym użycie stopera dla większej precyzji.

Stopwatch sw = new Stopwatch();
sw.Start();
// Do Work
sw.Stop();

Console.WriteLine("Elapsed time: {0}", sw.Elapsed.TotalMilliseconds);

Alternatywnie, jeśli potrzebujesz czegoś bardziej wyrafinowanego, prawdopodobnie powinieneś rozważyć użycie zewnętrznego profilera, takiego jak ANTS .

 93
Author: mmcdole,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-02 14:08:39

Ten artykuł mówi, że przede wszystkim trzeba porównać trzy alternatywy, Stopwatch, DateTime.Now i DateTime.UtcNow.

Pokazuje również, że w niektórych przypadkach (gdy licznik wydajności nie istnieje) Stopwatch używa DateTime.UtcNow + jakieś dodatkowe przetwarzanie. Z tego powodu jest oczywiste, że w tym przypadku DateTime.UtcNow jest najlepszą opcją (ponieważ inne używają go + niektóre przetwarzanie)

Jednak, jak się okazuje, licznik prawie zawsze istnieje-zobacz Wyjaśnienie o licznik wydajności wysokiej rozdzielczości i jego istnienie związane ze stoperem. NET?.

Oto wykres wydajności. Zauważ, jak niski koszt wydajności UtcNow w porównaniu do alternatyw:

Tutaj wpisz opis obrazka

Oś X jest wielkością danych próbki, a oś Y jest względnym czasem przykładu.

Jedna rzecz Stopwatch jest lepsza w tym, że zapewnia wyższą rozdzielczość pomiarów czasu. Inną jest jego bardziej OO natura. Jednak tworzenie wrappera OO wokół UtcNow nie może być mocno.

 57
Author: Valentin Kuzub,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:19

Przydatne jest przeniesienie kodu porównawczego do klasy/metody użytkowej. Klasa StopWatch nie musi być Disposed lub Stopped W przypadku błędu. Zatem najprostszym kodem czasu jakiejś akcji jest

public partial class With
{
    public static long Benchmark(Action action)
    {
        var stopwatch = Stopwatch.StartNew();
        action();
        stopwatch.Stop();
        return stopwatch.ElapsedMilliseconds;
    }
}

Przykładowy kod wywołujący

public void Execute(Action action)
{
    var time = With.Benchmark(action);
    log.DebugFormat(“Did action in {0} ms.”, time);
}

Oto wersja metody rozszerzenia

public static class Extensions
{
    public static long Benchmark(this Action action)
    {
        return With.Benchmark(action);
    }
}

I przykładowy kod wywołujący

public void Execute(Action action)
{
    var time = action.Benchmark()
    log.DebugFormat(“Did action in {0} ms.”, time);
}
 19
Author: Anthony Mastrean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-11-30 16:47:33

Funkcjonalność stopera byłaby lepsza (większa precyzja). Polecam również po prostu ściągnąć jeden z popularnych profilerów, chociaż (DotTrace i mrówki to te, z których korzystałem najczęściej... darmowa wersja próbna DotTrace jest w pełni funkcjonalna i nie zrzędzi jak niektóre inne).

 16
Author: jsight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-26 17:13:21

Użyj systemu.Diagnostyka.Zajęcia ze stoperem.

Stopwatch sw = new Stopwatch();
sw.Start();

// Do some code.

sw.Stop();

// sw.ElapsedMilliseconds = the time your "do some code" took.
 14
Author: rp.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-26 17:13:59

Ditto stoper, jest o wiele lepszy.

Jeśli chodzi o pomiar wydajności, powinieneś również sprawdzić, czy twój "/ / Some Execution Process " jest bardzo krótkim procesem.

Należy również pamiętać, że pierwsze uruchomienie "/ / Some Execution Process " może być znacznie wolniejsze niż kolejne.

Zazwyczaj testuję metodę, uruchamiając ją 1000 razy lub 1000000 razy w pętli i otrzymuję znacznie dokładniejsze dane niż uruchomienie jej raz.

 11
Author: Andrei Rînea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-30 14:24:33

Są to świetne sposoby pomiaru czasu, ale jest to tylko bardzo pośredni sposób, aby znaleźć wąskie gardło(s).

Najbardziej bezpośrednim sposobem na znalezienie bottneck w wątku jest uruchomienie go, a gdy robi to, co sprawia, że czekasz, zatrzymaj go za pomocą pauzy lub klawisza break. Zrób to kilka razy. Jeśli wąskie gardło zajmuje X% czasu, X% to prawdopodobieństwo, że złapiesz go w akcie na każdym migawce.

Oto pełniejsze wyjaśnienie, jak i dlaczego to działa

 9
Author: Mike Dunlavey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:41

@Sean Chambers

Dla twojej wiadomości, Klasa. NET Timer nie służy do diagnostyki, generuje zdarzenia w zadanym interwale, jak to (z MSDN):

System.Timers.Timer aTimer;
public static void Main()
{
    // Create a timer with a ten second interval.
    aTimer = new System.Timers.Timer(10000);

    // Hook up the Elapsed event for the timer.
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer.Interval = 2000;
    aTimer.Enabled = true;

    Console.WriteLine("Press the Enter key to exit the program.");
    Console.ReadLine();
}

// Specify what you want to happen when the Elapsed event is 
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}

Więc to naprawdę nie pomaga Ci wiedzieć, jak długo coś trwało, tylko że upłynęła pewna ilość czasu.

Timer jest również wyświetlany jako sterowanie w systemie.Okna.Formularze... możesz go znaleźć w swojej skrzynce narzędzi projektanta w vs05 / VS08

 7
Author: Adam Haile,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:16

To jest poprawny sposób:

using System;
using System.Diagnostics;

class Program
{
    public static void Main()
    {
        Stopwatch stopWatch = Stopwatch.StartNew();

            // some other code

        stopWatch.Stop();

        // this not correct to get full timer resolution
        Console.WriteLine("{0} ms", stopWatch.ElapsedMilliseconds);

        // Correct way to get accurate high precision timing
        Console.WriteLine("{0} ms", stopWatch.Elapsed.TotalMilliseconds);
    }
}

Aby uzyskać więcej informacji, przejdź do Użyj stopera zamiast DataTime, aby uzyskać dokładny licznik wydajności.

 7
Author: jiya jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-21 20:38:14

Visual Studio Team System posiada kilka funkcji, które mogą pomóc w rozwiązaniu tego problemu. Zasadniczo można pisać testy jednostkowe i mieszać je w różnych scenariuszach, aby uruchamiać je z oprogramowaniem w ramach testu obciążenia lub obciążenia. Może to pomóc w identyfikacji obszarów kodu, które mają największy wpływ na wydajność aplikacji.

Microsoft ' Patterns and Practices group ma kilka wskazówek w Visual Studio Team System Performance Testing Guidance.

 6
Author: Iain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-21 20:39:11

Właśnie znalazłem wpis na blogu Vance ' a Morrisona o klasie Kodetimer , który napisał, że ułatwia korzystanie StopWatch i robi kilka fajnych rzeczy na boku.

 5
Author: OwenP,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-08 21:02:03

Sposób, w jaki używam w moich programach, to używanie klasy StopWatch, jak pokazano tutaj.

Stopwatch sw = new Stopwatch();
sw.Start();


// Critical lines of code

long elapsedMs = sw.Elapsed.TotalMilliseconds;
 5
Author: Blackvault,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-04 22:19:10

To nie jest wystarczająco Profesjonalne:

Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

Bardziej wiarygodną wersją jest:

PerformWork();

int repeat = 1000;

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < repeat; i++)
{
   PerformWork();
}

sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds / repeat);

W moim prawdziwym kodzie dodam GC.Zbieraj wywołania, aby zmienić zarządzaną stertę do znanego stanu i dodaj wywołanie uśpienia, aby różne interwały kodu mogły być łatwo oddzielone w profilu ETW.

 5
Author: Bye StackOverflow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-13 06:10:20

Zrobiłem bardzo mało tego rodzaju sprawdzania wydajności (mam tendencję do po prostu myśleć "to jest wolne, zrobić to szybciej"), więc mam prawie zawsze z tym.

Google ujawnia wiele zasobów / artykułów do sprawdzania wydajności.

Wiele wzmianek używa pinvoke, aby uzyskać informacje o wydajności. Wiele materiałów, które studiuję, wspomina tylko o użyciu perfmon..

Edit:

Widziałem rozmowy stopera.. Nieźle! Czegoś się nauczyłem:)

To wygląda na dobry artykuł

 4
Author: Rob Cooper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Ponieważ nie dbam zbytnio o precyzję, skończyłem porównując je. Przechwytuję wiele pakietów w sieci i chcę umieścić czas, Kiedy otrzymam każdy pakiet. Oto kod, który testuje 5 milionów iteracji

    int iterations = 5000000;

    // Test using datetime.now
    {
        var date = DateTime.UtcNow.AddHours(DateTime.UtcNow.Second);

        var now = DateTime.UtcNow;

        for (int i = 0; i < iterations; i++)
        {
            if (date == DateTime.Now)
                Console.WriteLine("it is!");
        }
        Console.WriteLine($"Done executing {iterations} iterations using datetime.now. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
    }

    // Test using datetime.utcnow
    {
        var date = DateTime.UtcNow.AddHours(DateTime.UtcNow.Second);

        var now = DateTime.UtcNow;

        for (int i = 0; i < iterations; i++)
        {
            if (date == DateTime.UtcNow)
                Console.WriteLine("it is!");
        }
        Console.WriteLine($"Done executing {iterations} iterations using datetime.utcnow. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
    }

    // Test using stopwatch
    {
        Stopwatch sw = new Stopwatch();
        sw.Start();

        var now = DateTime.UtcNow;

        for (int i = 0; i < iterations; i++)
        {
            if (sw.ElapsedTicks == DateTime.Now.Ticks)
                Console.WriteLine("it is!");
        }
        Console.WriteLine($"Done executing {iterations} iterations using stopwatch. It took {(DateTime.UtcNow - now).TotalSeconds} seconds");
    }

Wyjście To:

Done executing 5000000 iterations using datetime.now. It took 0.8685502 seconds 
Done executing 5000000 iterations using datetime.utcnow. It took 0.1074324 seconds 
Done executing 5000000 iterations using stopwatch. It took 0.9625021 seconds

Podsumowując DateTime.UtcNow jest najszybszy, jeśli nie zależy Ci zbytnio na precyzji . To również wspiera odpowiedź https://stackoverflow.com/a/6986472/637142 od tego pytania.

 0
Author: Tono Nam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-21 17:46:26