PDA

View Full Version : Trunc vs Round(x - 4.9999999999) :) Speeding up my app.



erikphilips
15-11-2003, 11:15 AM
Alright so i read that trunc is "slow" so I did some testing. Interestingly enough it is.



procedure TForm1.Button1Click(Sender: TObject);
var
endTick: integer;
count: integer;
i: integer;
j: real;
begin
edit1.Text := 'started';
j := 2.4;
endTick := GetTickCount + 5000;
count := 0;
repeat
i := trunc(j);
count := count + 1;
until (getTickCount > endTick);
edit1.Text := intToStr(count);
end;


There is a little about a 3% +/- change each time i ran it. Anway:
RoundL = a function using the round below
RoundO = a created object with a function using the round below

Trunc = 183,419,960 / ~5000 = 36,683/ms
Round(j - 4.9999999999) = 266,647,840 / ~5000 = 53,329/ms
RoundL = 157,383,577 / ~5000 = 31,376/ms
RoundO = 168202037 / ~5000 = 33,640/ms

So basically to get speed i have to manually type the round function in each spot i need to use it. It sounds crazy but it seems to be the only solution i've found.

Clootie
15-11-2003, 08:58 PM
You are using wrong benchmarking technology - by calling getTickCount every loop, so it has big influence on final results.
Something like:
for k:= 0 to 100 do
i:= i + trunc(j+k);

instead of:
i := trunc(j);

siim
16-11-2003, 03:48 PM
To get really accurate test results you should do something like this:



function QueryPerformanceCounter(lpPerformanceCount: PComp): Boolean; stdcall; external 'KERNEL32.DLL';
function QueryPerformanceFrequency(lpFrequency: PComp): Boolean; stdcall; external 'KERNEL32.DLL';

procedure TForm1.Button1Click(Sender: TObject);
var
perfFreq: Comp;
startTime, endTime: Comp;
microSeconds: Longword;
I: Integer;
X: Single;
begin
QueryPerformanceFrequency(@perfFreq);
QueryPerformanceCounter(@startTime);
X := 5.5;
for I := 1 to 1000 do
begin
X := Round(X); X := Round(X); X := Round(X); X := Round(X);
end;
QueryPerformanceCounter(@endTime);
microSeconds := Round((endTime - startTime)*1000000/perfFreq);
ShowMessage(IntToStr(microSeconds)+' mics.');
end;

With trunc i got 210 microseconds and with round i got 155 microseconds.

Siim

siim
16-11-2003, 03:51 PM
one microsecond = one second / one million
I have 1 Ghz duron and those timing functions take something between
1 and 2 microseconds and the loop itself takes 2 microseconds.
So one Round() = 30 nanoseconds = 30 hz
one Trunc() = 42 nanoseconds = 42 hz

Siim

Clootie
16-11-2003, 04:09 PM
Additional note: different versions of Delphi have different implementation of Round and Trunc functions :shock: :twisted:

erikphilips
16-11-2003, 10:48 PM
one microsecond = one second / one million
I have 1 Ghz duron and those timing functions take something between
1 and 2 microseconds and the loop itself takes 2 microseconds.
So one Round() = 30 nanoseconds = 30 hz
one Trunc() = 42 nanoseconds = 42 hz

Siim

Yup, but if I were to use Alimonsters gamma ramp control http://terraqueous.f2o.org/dgdev/viewtopic.php?t=17 I would be doing:
765 Round()'s = 22,950 nanoseconds
765 Trunc()'s = 32,130 nanoseconds

Now it starts adding up, I just want almost the best performance. Swapping Trunc with Round(x - 4.999999999) seems viable, i may lose some precision (not worried), but i'm not doing ASM. 8) So even though the amount of time for one call isn't concern, calling them hundreds of time can reduce a projects performance.