Home > Programowanie > Optymalizacja działań matematycznych w Delphi

Optymalizacja działań matematycznych w Delphi

Mnożenie, potęgowanie, pierwiastkowanie, wszystkie te operacje trwają ułamek sekundy na obecnych maszynach, ułamek sekundy do czasu gdy nie musimy wykonać tysięcy czy miliony iteracji danego działania. W takiej sytuacji odpowiedni dobór użytych funkcji może mieć duży wpływ na czas trwania całej operacji.

W tym wpisie pokaże jakich błędów unikać pisząc w Delphi skomplikowane działania, aby nie marnować czasu użytkownika końcowego naszej aplikacji. Do dzieła!

Stałe

Zacznijmy od rzeczy najprostszej, wykluczania operacji których wynik jest zawsze taki sam. Głupota? Prosty przykład, obliczenia w których występuje liczba PI podniesiona do kwadratu. Wartość tego wyrażenia jest zawsze taka sama, gdyż PI wynosi zawsze tyle samo.

procedure TForm1.Button1Click(Sender: TObject);
var
  k: Double;
begin
  k := GetTickCount * Sqr(PI) + 4;
end;

W takiej sytuacji zamiast podnosić 3,14 za każdym razem do kwadratu, najlepiej wyliczyć sobie tą wartość chociażby na systemowym kalkulatorze i zadeklarować nową stałą. Rzecz jasna, jak wcześniej wspomniałem, ma to sens tylko gdy wykonujemy naprawdę dużo obliczeń – inaczej jest to sztuka dla sztuki.

procedure TForm1.Button1Click(Sender: TObject);
const
  PI_2 = 9.8696044010893586188344909998762;
var
  k: Double;
begin
  k := GetTickCount * PI_2 + 4;
end;

Unikanie dzielenia

Swego czasu, wyczytałem iż lepiej jest przykładowo mnożyć razy 0,5 niż dzielić przez 2. Próbowałem potwierdzić to różnymi testami, ale za każdym razem dostawałem identyczny wynik. Strzelam że obecne procesory lepiej sobie radzą z dzieleniem w stosunku do mnożenia liczb zmiennoprzecinkowych niż kiedyś.

Dlatego też porada ta nie ma dzisiaj większego sensu, ale warto o niej pamiętać.

Power, Sqr, Sqrt

Funkcja Power, analogicznie do swojej nazwy kryje w sobie dużą moc ;) , nie mniej, należy się jej wystrzegać jak ognia. Power przyjmuje 2 argumenty, pierwszym jest liczba którą chcemy podnieść do potęgi, a drugim wykładnik potęgi.

Daje to ogromne możliwości z uwagi na fakt iż jest to liczba zmiennoprzecinkowa. Nie mniej, w sytuacji w której podnosimy liczbę do potęgi drugiej, bądź wyciągamy pierwiastek stopnia drugiego bezwzględnie stosujmy funkcje Sqr oraz Sqrt. Pierwiastek 4 stopnia? Zagnieżdżone dwie funkcję Sqrt będą na pewno szybsze niż jeden Power.

Oto małe porównanie szybkości wykonywania się poszczególnych operacji:

Funkcja Czas wykonania
Sqr(x) 0,0547ms
Sqrt(x) 0,6396ms
Power(x, 2) 0,8642ms
Power(x, 0.5) 3,9702ms

I na koniec wynik testu z pierwiastkiem czwartego stopnia:

Funkcja Czas wykonania
Sqrt(Sqrt(x)) 1,7472ms
Power(x, 0.25) 4,5896ms

Podsumowanie

Liczę że te kilka porad pozwoli Wam na optymalizację wielokrotnie wykonywanych działań matematycznych w Delphi. Oczywiście należy też pamiętać o doprowadzeniu danego równania do jak najprostszej postaci przed przystąpieniem do implementacji w programie.

  1. seler
    16 sierpnia 2010 at 00:41 | #1

    kurczę, aż od razu sprawdziłem. może nie odmierzałem odstępów czasowych, ale obserwowałem zużycie procka przez proces przy wykonywaniu pętli przez timer. mnożenie jest 2 razy szybsze! o_o zatem pamiętać o tym warto :P

  1. Brak jeszcze trackbacków