It is common knowledge that SameStr(S1, S2)
is faster than S1 = S2
, where var S1, S2: string
in Delphi.
(And, of course, SameText(S1, S2)
is much faster than AnsiLowerCase(S1) = AnsiLowerCase(S2)
.)
But, as far as I understand it, SameStr(S1, S2)
does exactly the same thing as S1 = S2
, so I cannot help but wonder why in the world the Delphi compiler doesn't use the SameStr
code when it test for string equality using the =
operator. Surely there must be a reason for this?
Some Benchmarking
A trivial program,
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils,
RejbrandCommon;
const
N = 1000000;
var
Strings1, Strings2: StringArray;
i: integer;
b: {dummy }boolean;
procedure CreateRandomStringArrays;
var
i: integer;
begin
SetLength(Strings1, N);
SetLength(Strings2, N);
for i := 0 to N - 1 do
begin
Strings1[i] := RandomString(0, 40);
Strings2[i] := RandomString(0, 40);
end;
end;
begin
CreateRandomStringArrays;
StartClock;
for i := 0 to N - 1 do
if Strings1[i] = Strings2[i] then
b := not b;
StopClock;
OutputClock;
StartClock;
for i := 0 to N - 1 do
if SameStr(Strings1[i], Strings2[i]) then
b := not b;
StopClock;
OutputClock;
Pause;
end.
where
function RandomString(const LowerLimit: integer = 2; const UpperLimit: integer = 20): string;
var
N, i: integer;
begin
N := RandomRange(LowerLimit, UpperLimit);
SetLength(result, N);
for i := 1 to N do
result[i] := RandomChar;
end;
and the inlined
function RandomChar: char;
begin
result := chr(RandomRange(ord('A'), ord('Z')));
end;
and the "clock" functions just wrap QueryPerformanceCounter
, QueryPerformanceFrequency
, and Writeln
, produces the output
2.56599325762716E-0002
1.24310093156453E-0002
ratio ~ 2.06
If the difference in length of the two strings that we compare is large, then the difference is even bigger. We try
Strings1[i] := RandomString(0, 0); // = '';
Strings2[i] := RandomString(0, 40);
and obtain
1.81630411160156E-0002
4.44662043198641E-0003
ratio ~ 4.08
So why doesn't the compiler use the SameStr
code when writing assembly for S1 = S2
?
Update
After reading Cosmin Prund's excellent answer, I couldn't resist setting
Strings1[i] := RandomString(40, 40);
Strings2[i] := RandomString(40, 40);
to produce strings of equal length and indeed.
2.74783364614126E-0002
1.96818773095322E-0002
ratio ~ 1.40
Hm... SameStr
still wins...
My Specs
CPU Brand String: Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz
Memory: 6 GB
OS: Windows 7 Home Premium (64-bit)
Compiler/RTL: Delphi 2009
Update
It would seem (see the comments below Cosmin Prund's excellent answer) like the =
operator was changed between D2009 and D2010. Can anyone confirm this?