通过分析(使用ProDelphi探查器)我的应用程序,我发现如果此功能更快,我可以获得更好的性能:
function BooleanToYN(isTrue: Boolean): string;
begin
if isTrue then
Result := 'Y'
else
Result := 'N';
end;
当我看到这段代码时,我认为它已经“优化”了。在你看来,这是加速它的方法吗? 还有其他评论吗?这是遗留代码,我没有写,所以不要问我为什么会这样。 当然,我可以考虑改变应用程序的编写方式,无论如何,如果有办法加快这个简单的功能(可能是使用另一个现成的Delphi函数),它会很棒。
答案 0 :(得分:9)
您的探查者很可能无法向您提供可靠的信息。这个功能是你程序的瓶颈,这简直难以置信。
改善该功能的主要选择是:
你会像这样实现选项2:
function BooleanToYN(isTrue: Boolean): string;
const
BoolStr: array [Boolean] of string = ('N', 'Y');
begin
Result := BoolStr[isTrue];
end;
当然,使函数内联是很有意义的。换句话说,应用上面的两个选项。
但如果这对你的节目表现有任何明显的不同,那将是惊人的。想一想。您的程序是否真的花费了很大一部分运行时执行该功能?真的?
分析非常困难,您应该期望分析者提供错误的信息。使用分析器时,您应该以潜在的不信任程度运行。始终最初对其输出持怀疑态度。
答案 1 :(得分:6)
我有一个理论认为Char会比String更快,但有时你只需要尝试它......
通过返回CHAR而不是String,可以将其提高16倍。我希望它与字符串的分配有关。
我将原始代码放入DUnit测试框架并添加了一个测试,以循环运行它1亿次。我把它叫做YNSLoop(S代表字符串),然后再做一个名为YNCLoop(C代表Char),它返回Char而不是String,然后我根据David的代码用Array做了另一个,然后我调用了YNALoop(A代表数组)。
然后根据大卫的建议我制作了原版的内联版本。这很好,所以我也制作了Inlined Char版本。嘿,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;