FUNCTION vs PROCEDURE
by: G.E. Ozz Nixon Jr.
Published: August 2009
©opyright 2009 by Friends of FPC
Well, I decided to test which is faster calling a function or calling a procedure. And
while I am at it, which parameter type is faster, none, var, constant, var of untyped.
Download parameter.pas source
Uses
dxutil_environment;// contains TimeCounter for Windows, Linux and Mac
function A1():Boolean;
begin
A1:=True;
end;
function B(Var A:Integer):Boolean;
begin
B:=True;
end;
function C(Const A:Integer):Boolean;
begin
C:=True;
end;
function D(A:Integer):Boolean;
begin
D:=True;
end;
function E(var A):Boolean;
begin
E:=True;
End;
procedure procA1();
Var
A1:Boolean;
begin
A1:=True;
end;
procedure procB(Var A:Integer);
Var
A1:Boolean;
begin
A1:=True;
end;
procedure procC(Const A:Integer);
Var
A1:Boolean;
begin
A1:=True;
end;
procedure procD(A:Integer);
Var
A1:Boolean;
begin
A1:=True;
end;
procedure procE(var A);
Var
A1:Boolean;
begin
A1:=True;
End;
Var
Loop:Longint;
StartTime:Comp;
I:Integer;
Begin
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do A1();
System.Write('A1: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do procA1();
System.Writeln(' procA1: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do B(I);
System.Write('B: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do procB(I);
System.Writeln(' procB: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do C(I);
System.Write('C: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do procC(I);
System.Writeln(' procC: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do D(I);
System.Write('D: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do procD(I);
System.Writeln(' procD: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do E(I);
System.Write('E: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do procE(I);
System.Writeln(' procE: ',Trunc(Trunc(TimeCounter)-StartTime));
end.
Well running this as is, you will see no matter what operating system you are on, that procedure calls
execute (return) faster. Now, if you were into assembly the reason is obvious, but I will state it here
anyway - functions require you to push and pop extra information (the result).
However, the other part that this exercise focused on was different parameter types. Calling a method
which takes no parameters of course is the fastest. A1 296ms and procA1 273ms. And you would expect
the "Var" type methods to be the slowest. B1 358ms and procB1 309ms. Or even the "Var" of untyped to
be the slowest. E1 341ms procE1 310ms. But, the slowest were the const and unspecified methods. C1 362ms
C1proc 316ms and D1 366ms D1proc 317ms.
Old school programmers were always taught to specify "const" to your parameters where possible. However,
somewhere along the way with modern compilers and facier CPUs, it appears that rule does not hold true anymore.
Now you should be asking yourself, so is it faster to have a procedure which does a var of the result, versus
a function that returns the result. The answer is, yes it is much faster! On Linux about 30% faster, it is
about 5 times faster!
Download which.pas source
Uses
dxutil_environment;// contains TimeCounter for Windows, Linux and Mac
function A1():AnsiString;
begin
A1:='';
end;
procedure procA1(var B:AnsiString);
begin
B:='';
end;
Var
Loop:Longint;
StartTime:Comp;
S:AnsiString;
Begin
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do A1();
System.Write('A1: ',Trunc(Trunc(TimeCounter)-StartTime));
StartTime:=Trunc(TimeCounter);
For Loop:=1 to 100000000 do procA1(S);
System.Writeln(' procA1: ',Trunc(Trunc(TimeCounter)-StartTime));
end.
G.E. Ozz Nixon Jr.