niedziela, 26 kwietnia 2009

Java: pomiar czasu wykonania kodu

"Czas to pieniądz" - powiedzenie stare jak świat. Aktualnie złożoność obliczeniowa algorytmów jest dużo ważniejsza niż ich złożoność pamięciowa. Nie zawsze możemy dokładnie wyliczyć złożoność obliczeniową. Możemy na szczęście wykonać szybki pomiar czasu wykonania naszego kodu dla przykładowych danych.

Na polskojęzycznych stronach znaleźć można oczywiście różne metody oparte często na klasie Time. My skorzystamy bezpośrednio z klasy System i jednej metody statycznej.

Metoda:
System.currentTimeMillis();

Zwraca nam aktualny czas w milisekundach. Nie ma wielkiej potrzeby analizować wykonania kodu z dokładnością do nanosekundy. Milisekundy w zupełności starczą. Jak więc użyć tej metody? To bardzo proste: pobieramy czas przed, czas po i odejmujemy je od siebie.

long start=System.currentTimeMillis();
//długie obliczenia
long stop=System.currentTimeMillis();
System.out.println("Czas wykonania:"+(stop-start));

Jak nie trudno zauważyć jest to bardzo proste w użyciu. Oczywiście pokusić się można o bardziej zaawansowany kod wykorzystujący przy okazji filozofię OOP. Zainteresowanych takim wykorzystaniem tego kodu odsyłam do strony gdzie sam znalazłem te informacje w języku angielskim: How to measure execution time.

Można mierzyć czas w odcinkach. Na przykład gdy najpierw kalkulujemy, a potem rysujemy, to możemy zmierzyć czas całościowo i czas obu etapów. Pojawia się oczywiście problem błędu spowodowanego przez pobranie czasu z systemu. Na szczęście przy dużych liczbach obliczeń czas wywołania tej metody można uznać za pomijalnie mały. Doradzam nie nadużywać tej metody jak każdej innej. Pomijalnie mały czas dla odpowiedniej liczby powtórzeń stanie się niedopuszczalnie duży i nasz pomiar czasu wykonania stanie się niedokładny. Mówiąc prościej: na pewno nie mierzymy w ten sposób czasu trwania każdej iteracji pętli jednocześnie mierząc czas trwania wszystkich iteracji. Różnica sumy i całego pomiaru może nas zaskoczyć.

Obrazek pochodzi z The Uber Review.

2 komentarze:

  1. System.currentTimeMillis();

    Zapomniałeś dodać że powyższa funkcja działa z dokładnością do 10ms, dla większej rozdzielczości warto użyć funkcji System.nanoTime() -> http://download.oracle.com/javase/1,5.0/docs/api/java/lang/System.html#nanoTime()

    Poza tym, trochę lejesz wodę.

    OdpowiedzUsuń
  2. @Anonimowy bo to jest takie miejsce w sieci, abym mógł w wolnej chwili i z potrzeby serca bezkarnie lać wodę i jednocześnie mieć czyste sumienie, bo może to być komuś przydatne w jakimś tam stopniu :).

    OdpowiedzUsuń