翻转bool:x =!x与x ^ = 1的性能比较

时间:2014-03-26 09:57:38

标签: c++ c optimization assembly

我知道两种翻转bool的技巧:

x = !x

x ^= 1

我更喜欢第二种,就像我喜欢x +而不是x + = 1而不是x = x + 1。

但他们是否可以保证生成相同的汇编代码?

如果没有,是否有理由支持一方而不是另一方?

4 个答案:

答案 0 :(得分:4)

对于相同的汇编代码,从来没有任何保证。是的,鉴于bool x,他们都做了完全相同的事情。是的,这意味着它们可能是相同的。

以不寻常的方式编写表达式可能会使它们更快,这是一种常见的谬误。避免与任何根据这些想法养成习惯的人合作。

x = ! x更清晰,因为!是根据布尔值定义的。

答案 1 :(得分:3)

  

我更喜欢第二种,就像我喜欢x +而不是x + = 1而不是x = x + 1。

请选择第一个。大多数程序员都期望并且容易理解。第二种形式,仅适用于整数&#39的值0和1。

  

但他们是否可以保证生成相同的汇编代码?

没有

  

如果没有,是否有理由支持一方而不是另一方?

降低" wtf / loc"的比率您的代码(即另一位开发人员会查看您的代码多少次,并且在每n行代码上说" WTF?!?")。

编辑:无论哪种方式,您都可能永远不会看到通过将一个表达式替换为另一个表达式来加快应用程序的实际示例。这是一种风格问题,而不是表现问题。

答案 2 :(得分:2)

第二个表达只是发现错误的难点之源。例如,你可能认为某个表达式的类型为bool,而由于整数提升或通常的算术转换,它的实际类型是某种整数类型。

请考虑以下代码段

unsigned int x = 3;

x ^= 1;

std::cout << x << std::endl;

if ( x == false ) std::cout << "All is O'k\n";
else std::cout << "Oops. Something is wrong!\n"; 

x = 3;

x = !x;

std::cout << x << std::endl;

if ( x == false ) std::cout << "All is O'k\n";
else std::cout << "Oops. Something is wrong!\n"; 

因此,使用表达式x ^= 1;来翻转布尔值只会使代码的读者感到困惑。

所以我更愿意使用x = !x;代替x ^= 1;

不要忘记 KISS 原则:保持简单愚蠢。:)

虽然例如在C中operator !的结果具有类型int但是操作的值是0或1。

来自C标准

  

5逻辑否定运算符的结果!如果值为0,则为0   它的操作数比较不等于0,1如果是其操作数的值   比较等于0。

因此对于两种语言都可以保证任何源值的结果都是0或1。

答案 3 :(得分:1)

!xx^1显然是不同的操作。

前者是逻辑否定,返回0/1值。在bools上使用它是有道理的。

后者是按位异或,或返回任何可能的值。它不应该用于布尔。 (对于xoring bools,更喜欢不等式比较!=)。它在未优化代码中的效率也低于它的调用和额外的操作数(1)。

K&amp; R忘了提供一个你会喜欢的!!运算符,可能~~