我最近一直在为我正在进行的研究项目编写一些代码,其中效率非常重要。我一直在考虑放弃我做事时使用的一些常规方法,改用按位异或。我想知道的是这是否会有所不同(如果我执行此操作说几百万次)或者我在 g++ 中使用 03 后它是否相同。
想到的两个例子:
我有一个例子(我正在处理纯正整数)如果 n 是奇数,我需要将 n 更改为 n-1,如果 n 是偶数,则需要将 n 更改为 (n+1)。我想我有几个选择:
if(n%2) // or (n%2==0) and flip the order
n=n-1
else
n=n+1
或
n=n+2*n%2-1; //This of course was silly, but was the only non-bitwise 1 line I could come up with
最后:
n=n^1;
所有方法显然都做同样的事情,但我的感觉是第三种方法最有效。
下一个例子更笼统。假设我正在比较两个正整数,其中一个会比其他的表现更好。或者即使我执行此操作几百万次,差异真的不会很明显吗:
if(n_1==n_2)
if(! (n_1 ^ n_2) )
if( n_1 ^ n_2) else \do work here
编译器是否会在所有这些实例中执行相同的操作?我只是好奇是否存在我应该使用按位运算而不相信编译器为我完成工作的实例。
修正:在正确的问题陈述中。
最佳答案
检查起来很容易,只需启动反汇编程序即可。看一看:
f.c:
unsigned int f1(unsigned int n)
{
n ^= 1;
return n;
}
unsigned int f2(unsigned int n)
{
if (n % 2)
n=n-1;
else
n=n+1;
return n;
}
构建和反汇编:
$ cc -O3 -c f.c
$ otool -tV f.o
f.o:
(__TEXT,__text) section
_f1:
00 pushq %rbp
01 movq %rsp,%rbp
04 xorl $0x01,%edi
07 movl %edi,%eax
09 leave
0a ret
0b nopl _f1(%rax,%rax)
_f2:
10 pushq %rbp
11 movq %rsp,%rbp
14 leal 0xff(%rdi),%eax
17 leal 0x01(%rdi),%edx
1a andl $0x01,%edi
1d cmovel %edx,%eax
20 leave
21 ret
看起来 f1()
有点短,这在现实中是否重要取决于一些基准测试。
关于c++ - 与更具可读性的方法相比,C++ 中按位异或的效率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2308293/