Muszę znaleźć wąskie gardło i precyzyjnie 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);
Odpowiedzi:
Nie, nie jest. Użyj stopera (w
System.Diagnostics
)Stoper automatycznie sprawdza istnienie precyzyjnych timerów.
Warto wspomnieć, że
DateTime.Now
często jest to nieco wolniejsze niżDateTime.UtcNow
ze względu na pracę, którą należy wykonać w strefach czasowych, DST i tym podobnych.DateTime.UtcNow zazwyczaj ma rozdzielczość 15 ms. Zobacz Johna Chapmana blogu o
DateTime.Now
dokładności do wielkiego podsumowania.Ciekawe ciekawostki: Stoper wraca,
DateTime.UtcNow
jeśli twój sprzęt nie obsługuje licznika wysokich częstotliwości. Możesz sprawdzić, czy stoper używa sprzętu do osiągnięcia wysokiej precyzji, patrząc na pole statyczne Stopwatch.IsHighResolution .źródło
PerformWork()
bardzo mało, możesz być w stanie zadzwonić do niego wielokrotnie i obliczyć średnią liczbę połączeń. Czas należy teżStopwatch
mierzyć całą serią połączeń, a nie uruchamiać / zatrzymywać, aby uniknąć efektu stroboskopowego, który zmąci twoje pomiary czasu.Jeśli chcesz czegoś szybkiego i brudnego, sugeruję użycie stopera zamiast tego dla większej precyzji.
Alternatywnie, jeśli potrzebujesz czegoś bardziej wyrafinowanego, prawdopodobnie powinieneś rozważyć użycie zewnętrznego profilera, takiego jak ANTS .
źródło
Ten artykuł mówi, że przede wszystkim musisz porównać trzy alternatywy
Stopwatch
,DateTime.Now
ANDDateTime.UtcNow
.Pokazuje także, że w niektórych przypadkach (gdy licznik wydajności nie istnieje) Stoper używa DateTime.UtcNow + dodatkowe przetwarzanie. Z tego powodu jest oczywiste, że w takim przypadku najlepsza jest opcja DateTime.UtcNow (ponieważ inni używają jej + trochę przetwarzania)
Jak się jednak okazuje, licznik prawie zawsze istnieje - patrz Objaśnienie dotyczące licznika wydajności wysokiej rozdzielczości i jego istnienia związanego z .NET Stopwatch? .
Oto wykres wydajności. Zauważ, jak niski koszt wydajności UtcNow w porównaniu z alternatywami:
Oś X to przykładowy rozmiar danych, a oś Y to czas względny z przykładu.
Jedna rzecz
Stopwatch
jest lepsza w tym, że zapewnia pomiary czasu w wyższej rozdzielczości. Innym jest jego bardziej charakter OO. Jednak utworzenie opakowania OOUtcNow
nie może być trudne.źródło
Przydatne jest umieszczenie kodu testu porównawczego w klasie / metodzie użyteczności.
StopWatch
Klasa nie musi byćDisposed
alboStopped
w przypadku błędu. Tak, to najprostszy kod do czasu niektóre działania jestPrzykładowy kod wywołujący
Oto wersja metody rozszerzenia
I przykładowy kod wywołujący
źródło
Elapsed.TotalMilliseconds
po większą precyzję. Zobacz też to pytanie stackoverflow.com/questions/8894425/…Funkcjonalność stopera byłaby lepsza (większa precyzja). Polecam również pobranie jednego z popularnych profilerów (jednak najczęściej korzystałem z DotTrace i ANTS ... bezpłatna wersja próbna DotTrace jest w pełni funkcjonalna i nie ma w tym nic dziwnego).
źródło
Użyj klasy System.Diagnostics.Stopwatch.
źródło
Ditto Stopwatch, jest o wiele lepszy.
Jeśli chodzi o pomiar wydajności, powinieneś również sprawdzić, czy Twój proces // // Some Execution Process jest bardzo krótki.
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 uzyskuję znacznie dokładniejsze dane niż raz.
źródło
Są to świetne sposoby mierzenia czasu, ale jest to tylko bardzo pośredni sposób na znalezienie wąskiego gardła (wąskich gardeł).
Najbardziej bezpośrednim sposobem na znalezienie wąskiego gardła w wątku jest uruchomienie go, a gdy robi to, co sprawia, że czekasz, zatrzymaj go za pomocą klawisza pauzy lub złamania. Zrób to kilka razy. Jeśli twoje wąskie gardło zajmuje X% czasu, X% to prawdopodobieństwo, że złapiesz go na akcie na każdej migawce.
Oto pełniejsze wyjaśnienie, w jaki sposób i dlaczego to działa
źródło
@ Sean Chambers
Do Twojej wiadomości, klasa .NET Timer nie jest przeznaczona do diagnostyki, generuje zdarzenia w ustalonych odstępach czasu, takich jak ten (z MSDN ):
To naprawdę nie pomaga wiedzieć, ile czasu zajęło, tylko że minęła pewna ilość czasu.
Timer jest również widoczny jako element sterujący w System.Windows.Forms ... można go znaleźć w skrzynce narzędzi projektanta w VS05 / VS08
źródło
To jest właściwy sposób:
Aby uzyskać więcej informacji, przejdź do Użyj stopera zamiast DataTime w celu uzyskania dokładnego licznika wydajności .
źródło
Visual Studio Team System ma pewne funkcje, które mogą pomóc w rozwiązaniu tego problemu. Zasadniczo możesz pisać testy jednostkowe i mieszać je w różnych scenariuszach, aby uruchomić je z oprogramowaniem w ramach testu obciążenia lub obciążenia. Pomoże to zidentyfikować obszary kodu, które mają największy wpływ na wydajność aplikacji.
Grupa Microsoft ds. Wzorców i praktyk zawiera wskazówki w Visual Studio Team System Performance Testing Guidance .
źródło
Właśnie znalazłem post na blogu Vance'a Morrisona na temat napisanej przez niego klasy CodeTimer , która ułatwia korzystanie z niej
StopWatch
i robi porządne rzeczy z boku.źródło
To nie jest wystarczająco profesjonalne:
Bardziej niezawodna wersja to:
W moim prawdziwym kodzie dodam wywołanie GC.Collect, aby zmienić sterowaną stertę na znany stan, i dodam wywołanie uśpienia, aby różne przedziały kodu można było łatwo rozdzielić w profilu ETW.
źródło
Zrobiłem bardzo niewiele z tego rodzaju sprawdzania wydajności (zwykle myślę, że „to jest powolne, przyspieszam”), więc prawie zawsze to robiłem.
Google ujawnia wiele zasobów / artykułów do sprawdzania wydajności.
Wielu wspomina o użyciu pinvoke w celu uzyskania informacji o wydajności. Wiele materiałów, które badam, wspomina tylko o użyciu perfmon.
Edytować:
Widziałem rozmowy StopWatch .. Fajnie! Nauczyłem się czegoś :)
To wygląda na dobry artykuł
źródło
Sposób, w jaki korzystam z moich programów, to użycie klasy StopWatch, jak pokazano tutaj.
źródło