我有一个理论认为 Char 会比 String 快,但有时你只需要尝试一下......
通过返回 CHAR 而不是 String,它可以提高 16 倍。我希望它与字符串的分配有关。
我将原始代码放入 DUnit 测试框架中,并添加了一个测试以将其循环运行 1 亿次。我将它称为 YNSLoop(S 表示字符串),然后制作了另一个称为 YNCLoop(C 表示 Char),它返回 Char 而不是 String,然后我根据 David 的代码用数组制作了另一个,我称之为 YNALoop(A 表示数组)。
然后,根据大卫的建议,我制作了原始版本的内联版本。那很好,所以我也做了一个内联字符版本。嘿,Char 版本的内联版本甚至更快。
YNSLoop: 4487 ms (Original)
YNSILoop: 1226 ms (Original, Inlined)
YNCLoop: 266 ms (Char instead of String)
YNCILoop: 124 ms (Char Inlined)
YNALoop: 4548 ms (Array)
结论:如果你可以使用 Char 而不是 String,那就去做吧。无论哪种方式,如果可以的话,内联它。
下面的代码:
function BooleanToYNSI(isTrue: Boolean): string; inline;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
function BooleanToYNS(isTrue: Boolean): string;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
function BooleanToYNC(isTrue: Boolean): Char;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
function BooleanToYNCI(isTrue: Boolean): Char; inline;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
function BooleanToYNArray(isTrue: Boolean): string;
const
BoolStr: array [Boolean] of string = ('N', 'Y');
begin
Result := BoolStr[isTrue];
end;
procedure TDBISAM_PERFTest.YNSLoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNS(True) <> 'Y' then
Fail('Failed');
end;
procedure TDBISAM_PERFTest.YNSILoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNSI(True) <> 'Y' then
Fail('Failed');
end;
procedure TDBISAM_PERFTest.YNCLoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNC(True) <> 'Y' then
Fail('Failed');
end;
procedure TDBISAM_PERFTest.YNCILoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNCI(True) <> 'Y' then
Fail('Failed');
end;
procedure TDBISAM_PERFTest.YNALoop;
var
i : integer;
begin
for i := 1 to 100000000 do
if BooleanToYNArray(True) <> 'Y' then
Fail('Failed');
end;