c++ - 与更具可读性的方法相比,C++ 中按位异或的效率

标签 c++ performance bitwise-operators

我最近一直在为我正在进行的研究项目编写一些代码,其中效率非常重要。我一直在考虑放弃我做事时使用的一些常规方法,改用按位异或。我想知道的是这是否会有所不同(如果我执行此操作说几百万次)或者我在 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/

相关文章:

c++ - 如何从 mp3 文件中提取音频数据?

arrays - 为什么在 Java 和 C 等语言中数组索引从 0 开始而不是从 1 开始?

vim - 如何在 Vim 中不进入插入模式的情况下在光标所在位置插入换行符?

c# - 检查是否仅在枚举中设置了这些标志

c++ - 如何在 C++ 中删除指向数组的指针

c++ - 在 C++ 中删除单词之间的所有空格

c++ - 使用 Matlab Coder 将 Matlab m 文件转换为 C/C++ 代码,包括 mex 文件 (mxArray)

java - 如何让高性能的矩阵算法实现分布式?

从 32 个字符中提取最后 16 个字符的 Python 代码

javascript - (-3>>>0).toString(2) 与 (-3>>0).toString(2)