我意识到差异可能可以忽略不计,但是在尝试将无符号长整数归零时哪个更有效?
unsigned long x;
...
x=0;
--OR--
x^=x;
泰勒
我意识到差异可能可以忽略不计,但是在尝试将无符号长整数归零时哪个更有效?
unsigned long x;
...
x=0;
--OR--
x^=x;
泰勒
如果你要实现一个编译器,你会怎么做?实际上,您会为两者选择最快的实现。由于两者是相等的,因此这种最快的实现对两者都是相同的。
换句话说,如果您启用优化,公元前 5000 年之后发布的任何编译器都将为两者生成相同的汇编x = 0
代码x ^= x
。这意味着它们同样快。
这不仅适用于赋值/异或,还适用于乘法等算法。表达您的意图并让编译器对其进行优化。相信我,编译器比你更擅长优化。
换句话说,编写可读的代码并使用x = 0;
.
哦,顺便说一句,按位异或一个未初始化的整数本身是未定义的行为,一个好的编译器应该优化整个事情。
首先,如果变量没有被赋值,从技术上讲,它是“未定义的行为”,除了赋值之外的任何事情。
其次,在过去 15 到 20 年生产的处理器上,对它自身进行 XOR 不太可能更快,因为它需要额外的读取。很长一段时间以前它可能更快(由于是更短的代码),但实际上,我相信即使这样也是错误的。
编辑:我应该指出,在现代处理器中,异或寄存器可能会更快/更紧凑,使其为零。但是如果我们假设我们不知道是否x
在寄存器中,那么我们也不应该让编译器更复杂地确定我们实际在做什么。
为什么要推测编译器的作用?让我们试试吧!
下面是一些测试代码:
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。