Pomiar czasu trwania procedury

fatalbomb

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

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

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

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.

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

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
Zaraz, zaraz.. w jaki sposób otrzymałeś pomiar tysiąc razy mniejszy od błędu pomiarowego? :O