假设我有一些像这样的代码:
if (ItemA = nil) then
Exit;
if (ItemB = '') then
Exit;
这样做会更快/更有效:
if (ItemA = nil) or (ItemB = '') then
Exit;
我意识到这很可能不会影响性能,但我只是好奇。
答案 0 :(得分:6)
他们是一样的。这是我的测试程序:
{$APPTYPE CONSOLE}
var
i, j: Integer;
begin
if (i=0) then
Exit;
if (j=0) then
Exit;
if (i=0) or (j=0) then
Exit;
Writeln('stop the compiler optimising away the final exit');
end.
使用32位编译器构建的发布版本的编译代码:
Project1.dpr.9: if (i=0) then 004060D5 85DB test ebx,ebx 004060D7 7426 jz $004060ff Project1.dpr.11: if (j=0) then 004060D9 85C0 test eax,eax 004060DB 7422 jz $004060ff Project1.dpr.13: if (i=0) or (j=0) then 004060DD 85DB test ebx,ebx 004060DF 741E jz $004060ff 004060E1 85C0 test eax,eax 004060E3 741A jz $004060ff
从64位编译器开始:
Project1.dpr.9: if (i=0) then 000000000040B49F 833D2A78000000 cmp dword ptr [rel $0000782a],$00 000000000040B4A6 743B jz Project1 + $63 Project1.dpr.11: if (j=0) then 000000000040B4A8 833D2578000000 cmp dword ptr [rel $00007825],$00 000000000040B4AF 7432 jz Project1 + $63 Project1.dpr.13: if (i=0) or (j=0) then 000000000040B4B1 833D1878000000 cmp dword ptr [rel $00007818],$00 000000000040B4B8 7429 jz Project1 + $63 000000000040B4BA 833D1378000000 cmp dword ptr [rel $00007813],$00 000000000040B4C1 7420 jz Project1 + $63
正如您所看到的,两个Windows编译器都为这两种变体生成相同的代码。我不能保证移动编译器,但如果他们有任何不同,我会感到震惊。
随意使用哪种感觉更容易阅读!
请注意,如果启用完整布尔评估选项(doc link 1,doc link 2),那么事情当然会发生变化。输出现在是:
Project1.dpr.9: if (i=0) then 004060D4 85C0 test eax,eax 004060D6 742B jz $00406103 Project1.dpr.11: if (j=0) then 004060D8 85D2 test edx,edx 004060DA 7427 jz $00406103 Project1.dpr.13: if (i=0) or (j=0) then 004060DC 85C0 test eax,eax 004060DE 0F94C0 setz al 004060E1 85D2 test edx,edx 004060E3 0F94C2 setz dl 004060E6 0AC2 or al,dl 004060E8 7519 jnz $00406103
我认为完全布尔评估显然会导致代码变慢。当然,完整的布尔评估是一个极端的案例,因为我会惊讶地发现任何使用它的场景。当然,如果被测试的表达式有副作用,它在逻辑上与你的两个if语句版本不同。