bool x = false, y = false, z = true;
if(x || y || z){}
or
if(x | y | z){}
第二个 if 语句是否对所有 boolean 值执行有点明智的“或”操作?把它们当作字节来对待?例如) (0000 | 0000 | 0001) = 真...
或者它的行为像Java |在 boolean 值上,即使第一个为真,它也会在哪里评估表达式中的每个 boolean 值?
我想知道按位运算符如何处理 boolean 值。是否等同于整数位运算?
最佳答案
效率靠谱,逻辑或运算符||
是短路运算符
这意味着如果您的示例中的 x
为真,它将不会评估 y
或 z
。
如果它是逻辑和 &&
,那么如果 x
为假,它将不会测试 y
或 z
。
需要注意的是,这个操作并不作为指令存在
所以这意味着你必须使用测试和跳转指令。这意味着分支,这会减慢速度。由于现代 CPU 是流水线的。
但真正的答案是视情况而定,就像许多其他此类问题一样,因为有时短路操作的好处大于成本。
在以下极其简单的示例中,您可以看到按位或 |
更胜一筹。
#include <iostream>
bool test1(bool a, bool b, bool c)
{
return a | b | c;
}
bool test2(bool a, bool b, bool c)
{
return a || b || c;
}
int main()
{
bool a = true;
bool b = false;
bool c = true;
test1(a,b,c);
test2(a,b,c);
return 0;
}
以下是 gcc-4.8 使用 -O3
生成的 intel 风格汇编列表:
test1
程序集:
_Z5test1bbb:
.LFB1264:
.cfi_startproc
mov eax, edx
or eax, esi
or eax, edi
ret
.cfi_endproc
test2
程序集:
_Z5test2bbb:
.LFB1265:
.cfi_startproc
test dil, dil
jne .L6
test sil, sil
mov eax, edx
jne .L6
rep; ret
.p2align 4,,10
.p2align 3
.L6:
mov eax, 1
ret
.cfi_endproc
你可以看到它有分支指令,这弄乱了流水线。
有时短路是值得的,例如
return x && deep_recursion_function();
免责声明:
我总是在 bools
上使用逻辑运算符。除非性能真的很关键,或者像 test1
和 test2
这样的简单情况,但有很多 boolean 值。
在任何一种情况下,首先验证您确实得到了改进。
关于c++ - C++ 中逻辑 "or"对 bool 值的效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18645907/