Programowanie w języku Pascal

Pomiar czasu trwania procedury

To już w zasadzie było opisane w artykule "Efektywne programowanie w Turbo Pascalu", ale warto to wyciągnąć do osobnego artykułu, bo nie każdemu chce się wczytywać w głąb tamtego.




Czas wykonywania procedury można określić mierząc go w ten sposób
var t: Longint absolute $0040:$006C;
 tb, te:Longint;
 
...
 
tb := t;
 Procedura_której_czas_mierzymy;
te := t;
 writeln ('Procedura wykonywała się ',(te-tb)/100:0:2,' s');


Zmienna t jest przypisana do adresu 0040:006C, pod którym siedzi licznik zegara czasu rzeczywistego. Potem wykorzystujemy tą zmienną jak funkcję. Jest to dużo bardziej efektywne od konstrukcji w stylu:
uses Dos;
function t:Longint;
var H,M,S,St:Word;
 GetTime (H,M,S,St);
 t := H*360000 + M*6000 + S*100+ St;
end;


Ale wróćmy do pomiarów czasu. Licznik czasu rzeczywistego jest aktualizowany 18.2 raza na sekundę, co daje dokładność plus/minus 55 milisekund. O wiele za dużo jak na nasze potrzeby: naprawdę długa procedura wywołuje się tyle czasu (chyba że dobieramy się do dyskietki czy duuużego pliku). Rozwiązaniem jest wywołać taką procedurę kilka(set) razy i podzielić czas przez liczbę wywołań:

var t: Longint absolute $0040:$006C;
 tb, te:Longint;
 N:Word;
 
...
 
tb := t;
 for N := 1 to 1000 do 
 Procedura_której_czas_mierzymy;
te := t;
{ Można zostawić wynik w sekundach... }
 writeln ('Procedura wykonywała się ',((te-tb)/100)/1000:0:6,' s'); 
 
{ ...albo zamienić od razu na mikrosekundy }
 writeln ('Procedura wykonywała się ',((te-tb)*10000)/1000,' us'); 


Ostateczna dokładność pomiaru to plus/minus 55/x milisekund, gdzie x to liczba wywołań procedury. W naszym przykładzie jest to 55 mikrosekund

5 komentarzy

chemik143 2008-01-15 00:51

jak już coś to +- 27,5sek... A poza tym zawsze można przerwanko przyspieszyć i będzie większa dokłąność

Marooned 2007-04-24 15:42

Ale to jakby średnią wtedy wyciągasz - chyba, że przyjmujesz identyczny czas wykonania kodu za każdym razem - wtedy się zgodzę.

fatalbomb 2007-04-23 22:14

Jeżeli z błędem 55 ms obliczamy czas 1000x większy, to dzieląc 55ms przez 1000 powtórzeń otrzymujemy dokładność do 55us. Jakbym wywołał milion razy, to błąd by wyniósł 55 nanosekund. Stosuję tą metodę i się sprawdza, faktycznie jest bardzo dokładna.

Coldpeer 2007-04-23 09:25

Korzystając z WinAPI można jeszcze skorzystać z funkcji GetTickCount o ile pamiętam

Marooned 2007-04-22 01:37

<quote>Ostateczna dokładność pomiaru to plus/minus 55/x milisekund, gdzie x to liczba wywołań procedury. W naszym przykładzie jest to 55 mikrosekund</quote>Zaraz, zaraz.. w jaki sposób otrzymałeś pomiar tysiąc razy mniejszy od błędu pomiarowego? :O