我想知道C ++中的速度或性能是否存在差异:
AND操作:&&, and, bitand
OR操作:||, or, bitor
或者所有人的表现相同?
答案 0 :(得分:4)
在详细说明之前,&&
和and
是等效的,&
和bitand
,||
和or
以及|
和bitor
。有关详细信息,请参阅cppreference.com
它们之间肯定存在差异,所以让我们更详细地看一下它们:
&&
和||
是逻辑运算符。他们的结果是true
或false
,没有别的
如果至少有一个操作数(||
)或两个操作数(&&
)不是false
,则结果为true
,否则为false
。< / p>
&
和|
是按位运算符。它们独立地操作每一个操作数
这主要用于对数字进行位操作,比如将数字的最低3位设置为0(考虑它们的二进制表示):
int result1 = number & 0b111;
// or to set the 3 lowermost bits to 1
int result2 = number | 0b111;
您可能知道,对于条件语句,C ++中的每个数字都可以解释为布尔值,更具体地说,0是false
,其他所有数字都是true
。这可能会导致一些混淆,如下例所示:
int a = 1;
int b = 2;
if (a && b) {
std::cout << "a && b\n";
}
if (a & b) {
std::cout << "a & b\n";
}
这将只输出a && b
,因为a & b
为0,因此false
,即使a
和b
都不是false
。
简而言之,对于逻辑操作使用&&
和||
,对于数字上的按位操作使用&
和|
,但请注意副作用:
除了不同的使用范围外,这些运算符之间还存在另一个差异,即逻辑运算符(&&
和||
)的强制短路评估。这意味着如果我们已经通过计算第一个操作数来知道表达式的结果,那么第二个操作数就不能进行评估。这意味着以下两段代码是等效的:
bool result = is_this_true() && is_that_true();
// equivalent:
bool result;
if (is_this_true()) {
result = is_that_true();
} else {
result = false;
}
逻辑或运算符也是如此:
bool result = is_this_true() || is_that_true();
// equivalent:
bool result;
if (is_this_true()) {
result = true;
} else {
result = is_that_true();
}
这是因为
&&
的其中一个操作数为false
,则结果始终为false
||
的其中一个操作数为true
,则结果始终为true
与按位运算符相比,这肯定会对性能产生影响,基本上有两种不同的方式:
如果is_that_true()
的评估需要花费很多时间,那么短路评估可能会节省您在结果短路的情况下的时间。
如果对is_this_true()
和is_that_true()
的评估都非常快但有副作用,编译器无法摆脱,那么由等效if
引入的附加分支声明可能涉及一个小的性能损失(更多细节,阅读分支错误预测)。但是,在大多数情况下,这种性能差异非常小,除非对这些逻辑运算符的评估是您的性能瓶颈(再次,这应该是非常不可能),否则您不应该担心它。
如果您想了解更多信息,已经有几个答案详细说明了短路评估的效果,例如,请参阅 Is short-circuiting logical operators mandated? And evaluation order?
答案 1 :(得分:1)
或者所有人的表现相同?
这是一个苹果/橘子问题。 and
和bitand
执行不同的工作。
示例:
bool both_nonzero(int x, int y)
{
return x and y;
}
bool have_corresponding_bits(int x, int y)
{
return bool(x bitand y);
}
相应的汇编程序(gcc-x86_64 -O3):
both_nonzero(int, int):
test edi, edi
setne al
test esi, esi
setne dl
and eax, edx
ret
have_corresponding_bits(int, int):
test edi, esi
setne al
ret
正如您所看到的,第二个功能需要更少的指令,但从CPU的角度来看,它执行的任务更简单(按位操作是CPU的基础和黄油)生活的工作)。