var S1, S2: string
,使用SameStr(S1, S2)
比S1 = S2
更快。
(当然,SameText(S1, S2)
比AnsiLowerCase(S1) = AnsiLowerCase(S2)
要快得多。)
但据我所了解,SameStr(S1, S2)
和S1 = S2
的功能完全相同,所以我不禁想知道为什么Delphi编译器在使用=
运算符测试字符串相等时没有使用SameStr
代码。毫无疑问,这肯定有原因吧?
一些基准测试
一个微不足道的程序:
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.
在哪里
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;
并且内联的
function RandomChar: char;
begin
result := chr(RandomRange(ord('A'), ord('Z')));
end;
"clock"函数只是对QueryPerformanceCounter
, QueryPerformanceFrequency
, 和 Writeln
进行了包装,输出结果。
2.56599325762716E-0002
1.24310093156453E-0002
ratio ~ 2.06
如果我们要比较的两个字符串长度相差很大,那么它们之间的差异会更加明显。我们会尝试Strings1[i] := RandomString(0, 0); // = '';
Strings2[i] := RandomString(0, 40);
获取并获得
1.81630411160156E-0002
4.44662043198641E-0003
ratio ~ 4.08
所以为什么编译器在为 S1 = S2 生成汇编代码时不使用 SameStr 代码呢?更新
阅读了 Cosmin Prund 的出色回答后,我忍不住设置了。
Strings1[i] := RandomString(40, 40);
Strings2[i] := RandomString(40, 40);
生成长度相等的字符串。
2.74783364614126E-0002
1.96818773095322E-0002
ratio ~ 1.40
嗯... SameStr
仍然胜出...
我的规格
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
更新
(请查看Cosmin Prund的回答下面的评论),似乎=运算符在D2009和D2010之间发生了变化。有人可以证实吗?