多个If语句与使用逻辑运算符计算条件的单个语句的比较

Multiple If statements versus single statement with conditions evaluated using logical operators

本文关键字:语句 条件 比较 单个 计算 If 多个 逻辑运算符      更新时间:2023-10-16

我正在编写一个函数,该函数在实际执行任务之前检查几个条件。这是由许多if语句完成的。像这样:

bool foo()
{
if(invalid())
return false;
if(dont_execute())
return false;
// .. etc
// Actual execution here
return true;
}

在该功能中,将多个条件更改为是否有任何好处

bool foo()
{
if(invalid() || dont_execute() /* || .. etc */)
return false;
// Actual execution here
return true;
}

我觉得第一种风格可读性更强。我想知道的是,使用多个if语句而不是使用逻辑运算符进行组合是否会对性能产生影响。

不存在任何性能影响。如果我们比较两个函数的汇编,我们可以看到这两个函数是相同的。

示例:

bool f1();
bool f2();
bool combined()
{
if (f1() || f2())
return false;
return true;
}
bool separate()
{
if (f1())
return false;
if (f2())
return false;
return true;
}

这里是组装:

combined():
sub     rsp, 8
call    f1()
mov     r8d, eax
xor     eax, eax
test    r8b, r8b
jne     .L1
call    f2()
xor     eax, 1
.L1:
add     rsp, 8
ret
separate():
sub     rsp, 8
call    f1()
mov     r8d, eax
xor     eax, eax
test    r8b, r8b
jne     .L7
call    f2()
xor     eax, 1
.L7:
add     rsp, 8
ret

使用测试用例

bool invalid();
bool dont_execute();
void execute();
bool foo()
{
if(invalid())
return false;
if(dont_execute())
return false;
execute();
return true;
}
bool foo2()
{
if(invalid() || dont_execute() /* || .. etc */)
return false;
execute();
return true;
}

您可以看到,foofoo2都是由GCC 9.2和Clang 9使用-O2优化标志编译成完全相同的程序集的,请参见godbolt。例如GCC的输出是

foo():
sub     rsp, 8
call    invalid()
test    al, al
je      .L2
.L4:
xor     eax, eax
add     rsp, 8
ret
.L2:
call    dont_execute()
test    al, al
jne     .L4
call    execute()
mov     eax, 1
add     rsp, 8
ret
foo2():
sub     rsp, 8
call    invalid()
test    al, al
je      .L8
.L10:
xor     eax, eax
add     rsp, 8
ret
.L8:
call    dont_execute()
test    al, al
jne     .L10
call    execute()
mov     eax, 1
add     rsp, 8
ret

虽然这并不意味着永远不会有区别,但至少编译器认为他们不需要在这两种情况下做任何不同的事情,即使他们不知道被调用的函数的作用。

因此,我建议您不要担心性能,而是选择您认为可读性更强的内容。