c++ - C++ 中逻辑 "or"对 bool 值的效率

标签 c++ boolean bitwise-operators

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 为真,它将不会评估 yz。 如果它是逻辑和 &&,那么如果 x 为假,它将不会测试 yz。 需要注意的是,这个操作并不作为指令存在 所以这意味着你必须使用测试和跳转指令。这意味着分支,这会减慢速度。由于现代 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 上使用逻辑运算符。除非性能真的很关键,或者像 test1test2 这样的简单情况,但有很多 boolean 值。 在任何一种情况下,首先验证您确实得到了改进。

关于c++ - C++ 中逻辑 "or"对 bool 值的效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18645907/

相关文章:

c++ - 什么时候实例化类模板?

c++ - 如何在 C++ 中将字符串作为 shell 脚本执行?

python - 如何合并2个具有不同列的 boolean 数据框?

java - 二元运算符 & 的错误操作数类型

c++ - == 比按位 AND、XOR 和 OR 具有更高优先级的理由是什么?

c++ - 这是 operator<</>> 的正确实现吗?

c++ - 在函数中使用方程式的麻烦

c++ - 套接字编程 : 'accept: Bad file descriptor'

java - 如何使用具有字符输入和 boolean 输出的方法?

java - 仅当输入为 "true"或 "false"时才将字符串转换为 boolean 值