9

我意识到差异可能可以忽略不计,但是在尝试将无符号长整数归零时哪个更有效?

unsigned long x;

...

x=0;

--OR--

x^=x;

泰勒

4

3 回答 3

32

如果你要实现一个编译器,你会怎么做?实际上,您会为两者选择最快的实现。由于两者是相等的,因此这种最快的实现对两者都是相同的。

换句话说,如果您启用优化,公元前 5000 年之后发布的任何编译器都将为两者生成相同的汇编x = 0代码x ^= x。这意味着它们同样快。

这不仅适用于赋值/异或,还适用于乘法等算法。表达您的意图并让编译器对其进行优化。相信我,编译器比你更擅长优化。

换句话说,编写可读的代码并使用x = 0;.


哦,顺便说一句,按位异或一个未初始化的整数本身是未定义的行为,一个好的编译器应该优化整个事情。

于 2013-04-04T16:42:38.710 回答
11

首先,如果变量没有被赋值,从技术上讲,它是“未定义的行为”,除了赋值之外的任何事情。

其次,在过去 15 到 20 年生产的处理器上,对它自身进行 XOR 不太可能更快,因为它需要额外的读取。很长一段时间以前它可能更快(由于是更短的代码),但实际上,我相信即使这样也是错误的。

编辑:我应该指出,在现代处理器中,异或寄存器可能会更快/更紧凑,使其为零。但是如果我们假设我们不知道是否x在寄存器中,那么我们也不应该让编译器更复杂地确定我们实际在做什么。

于 2013-04-04T16:43:42.987 回答
2

为什么要推测编译器的作用?让我们试试吧!

下面是一些测试代码:

void fzero()
{
   unsigned long x;

   x = 0;
}

void fxor()
{
   unsigned long x;

   x ^= x;
}


int main()
{
   fzero();
   fxor();
}

现在让我们看看生成的机器代码:

; 10   :    unsigned long x;
; 11   : 
; 12   :    x ^= x;
; 13   : }

00000   c2 00 00     ret     0

; 3    :    unsigned long x;
; 4    : 
; 5    :    x = 0;
; 6    : }

00000   c2 00 00     ret     0

PUBLIC  main
; Function compile flags: /Ogtpy
;   COMDAT main
_TEXT   SEGMENT
main    PROC                        ; COMDAT

; 18   :    fzero();
; 19   :    fxor();
; 20   : }

  00000 33 c0        xor     eax, eax
  00002 c3       ret     0
main    ENDP

哦,看!它们的速度同样快,都正好是 0 ns。

于 2013-04-04T18:23:44.153 回答