Pokazywanie postów oznaczonych etykietą czas. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą czas. Pokaż wszystkie posty

poniedziałek, 22 sierpnia 2011

C# - pomiar czasu wykonania kodu

Udało mi się dzisiaj zakończyć implementację projektu w C# (C Sharp), który już raz był inspiracją do postu na tym blogu. Przyszła więc pora na przeprowadzenie testów na aplikacji. Poza sprawdzeniem wymagań funkcjonalnych konieczne jest zbadanie wszystkich wymagań niefunkcjonalnych. Najłatwiejsze z nich do sprawdzenia, to czas realizacji funkcjonalności. Dzisiaj więc post o pomiarze czasu wykonania kodu w C#. Stosuję elegancką i wygodną metodę z C# 2.0.

sobota, 14 maja 2011

Java: Android i pomiar czasu wykonania kodu

Misją tego bloga jest rozpowszechnianie rozwiązań, których znalezienie, lub opracowanie zajęło mi nieco czasu i przyniosło korzyści. Właściwie to się nie zmieniło. Zdarza mi się co najwyżej rozwiązywać ten sam problem w innym nieco ujęciu. Bardzo duży ruch na blogu generuje wpis o pomiarze czasu w języku Java. Tym razem coś bardzo zbliżonego, bo o pomiarze czasu na platformie Android. Praktycznie nic się nie różni, ale zawsze to wygodna ściągawka.

poniedziałek, 26 października 2009

ASM: pomiar czasu wykonania kodu

Tak sobie co jakiś czas sprawdzam statystyki mojego bloga i okazuje się, że ludzie trafiają tu szukając rozwiązania problemu mierzenia czasu w assemblerze. Do tego jeszcze dwóch ciekawych rzeczy się dowiedziałem. Po pierwsze nie ma w sieci po polsku dobrze rozwiązanego tego problemu, albo nie ma go w ogóle, a po drugie mój blog pojawia się w wynikach wysoko przy tych poszukiwaniach. W tej sytuacji pozostało mi tylko odszukać rozwiązanie i opisać je samemu.

Aby więc zmierzyć czas wykonania kodu w assemblerze należy skorzystać z real-time clock wbudowanego w naszą maszynę i obsługiwanego przez BIOS. Niestety ma to 'urządzenie' pewną wadę. Mianowicie jego przerwanie generowane jest w stałych, stosunkowo dużych odstępach czasu, a dokładnie 55ms. Bez wątpienia nie nada się to do mierzenia czasu wykonania pojedynczych operacji.

Odczyt z RTC można wykonać korzystając z przerwania  1Ah i jego funkcji 00h. W wyniku w CX:DX otrzymujemy liczbę taktów od północy, a takt jak pamiętamy ma 55ms. Do tego jeszcze w AL uzyskkamy informację czy system pracuje dłużej niż 24h. Czyli jeśli pracuje dłużej niż 24h, to AL=1. Dokładne dane na temat tego przerwania można znaleźć w The Art Of Assembly Language Programming.

Tak jak w przypadku każdego pomiaru czasu należy pobrać wartości przed badanym blokiem i po nim, a następnie pierwszą odjąć od drugiej. Tutaj widać 2 niedogodności:
  1. trzeba odjąć od siebie 2 podwójne słowa,
  2. pomiar może być niedokładny.
 Wiemy jednak, że liczba druga jest większa lub równa pierwszej, więc możemy odjąć od siebie liczby po słowie i nie martwić się o pożyczki, a co do drugiego problemu, to maksymalny błąd wyniesie 54ms, czyli możemy uznać, że będzie pomijalnie mały. Oczywiście to zależy od tego co mierzymy. Jak zmierzymy wykonanie jednej instrukcji, to błąd będzie na poziomie 100% i możemy te dane wyrzucić. Jak zawsze działać należy z głową.

Wnikliwy umysł zauważy jeszcze jeden możliwy problem. Jeśli w czasie naszego pomiaru następi północ, to dowiemy się tylko, że była. Jeśli wystąpi raz, to jeszcze możemy wyliczyć czas do jej wystąpienia od startu i wyliczyć cały pomiar. Jeśli wystapi więcej niż raz, to niestety cały pomiar możemy wyrzucić, bo nie dowiemy się ile razy wystąpiła. W tej sytuacji pozostaje nam tylko skorzystanie z zegara systemowego (CMOS), który niestety ma dokładność do 1s, ale przyda się do takich dużych pomiarów.

Obrazek pochodzi z Freies Magazine.

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.