假设我有一些这样的代码:

if (ItemA = nil) then
  Exit;
if (ItemB = '') then
  Exit;


这样做会更快/更有效:

if (ItemA = nil) or (ItemB = '') then
  Exit;


我意识到这很可能不会显着影响性能,但是我很好奇。

最佳答案

他们是一样的。这是我的测试程序:

{$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:如果(i = 0),则
004060D5 85DB测试ebx,ebx
004060D7 7426 jz $ 004060ff
Project1.dpr.11:如果(j = 0)则
004060D9 85C0测试eax,eax
004060DB 7422 jz $ 004060ff
Project1.dpr.13:如果(i = 0)或(j = 0),则
004060DD 85DB测试ebx,ebx
004060DF 741E jz $ 004060ff
004060E1 85C0测试eax,eax
004060E3 741A jz $ 004060ff


而从64位编译器中:

Project1.dpr.9:如果(i = 0),则
000000000040B49F 833D2A78000000 cmp dword ptr [rel $ 0000782a],$ 00
000000000040B4A6 743B jz Project1 + $ 63
Project1.dpr.11:如果(j = 0)则
000000000040B4A8 833D2578000000 cmp dword ptr [rel $ 00007825],$ 00
000000000040B4AF 7432 jz Project1 + $ 63
Project1.dpr.13:如果(i = 0)或(j = 0),则
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 1doc link 2),则情况当然会发生变化。现在的输出是:

Project1.dpr.9:如果(i = 0),则
004060D4 85C0测试eax,eax
004060D6 742B jz $ 00406103
Project1.dpr.11:如果(j = 0)则
004060D8 85D2测试版,EDX
004060DA 7427 jz $ 00406103
Project1.dpr.13:如果(i = 0)或(j = 0),则
004060DC 85C0测试eax,eax
004060DE 0F94C0设定
004060E1 85D2测试EDX,EDX
004060E3 0F94C2 SETZ DL
004060E6 0AC2或al,dl
004060E8 7519日元$ 00406103


我认为很明显,完整的布尔值评估会导致代码变慢。当然,完整的布尔值评估是一个极端的案例,因为我会惊讶地发现使用它的任何情况。当然,如果要测试的表达式有副作用,则在逻辑上与您的两个if语句版本在逻辑上是不同的。

08-03 13:58