多个 If 语句与使用逻辑运算符评估条件的单个语句
Multiple If statements versus single statement with conditions evaluated using logical operators
我正在编写一个函数,在实际执行任务之前检查几个条件。这是通过许多 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 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;
}
您可以看到 foo
和 foo2
都被 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
虽然这并不意味着永远不会有区别,至少编译器认为他们不需要在这两种情况下做任何不同的事情,即使他们不知道调用的函数是做什么的。
所以我建议您不要担心性能,而是选择您认为更具可读性的内容。
不,没有性能影响。如果我们 compare the assembly 这两个函数,我们可以看到这两个函数是相同的。
示例:
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
我正在编写一个函数,在实际执行任务之前检查几个条件。这是通过许多 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 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;
}
您可以看到 foo
和 foo2
都被 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
虽然这并不意味着永远不会有区别,至少编译器认为他们不需要在这两种情况下做任何不同的事情,即使他们不知道调用的函数是做什么的。
所以我建议您不要担心性能,而是选择您认为更具可读性的内容。
不,没有性能影响。如果我们 compare the assembly 这两个函数,我们可以看到这两个函数是相同的。
示例:
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