C/C++: adding 0
C/C++: adding 0
我在函数中有以下一行来计算序列中'G'和'C'的个数:
count += (seq[i] == 'G' || seq[i] == 'C');
编译器是否足够聪明,当它们看到'count += 0'时什么都不做,或者它们实际上浪费了'添加' 0的时间?
一般
x += y;
比
快if (y != 0) { x += y; }
即使是y = 0
,因为第一个选项中没有分支。如果它真的很重要,您将不得不检查编译器的输出,但不要认为您的方法更快,因为它有时不执行add。
老实说,谁在乎呢?
[编辑:]这实际上有点有趣。与我最初的假设相反,在未优化的编译中,n += b;
优于n += b ? 1 : 0;
。然而,通过优化,两者是相同的。更重要的是,这种形式的优化版本总是优于if (b) ++n;
,后者总是创建cmp/je
指令。(/编辑)
如果您非常好奇,请将以下代码放入编译器并比较生成的程序集!(一定要测试各种优化设置)
int n;
void f(bool b) { n += b ? 1 : 0; }
void g(bool b) { if (b) ++n; }
我用GCC 4.6.1测试了它:使用g++
并且没有优化,g()
更短。然而,对于-O3
, f()
更短:
g(): f():
cmpb $0, 4(%esp) movzbl 4(%esp), %eax
je .L1 addl %eax, n
addl $1, n
.L1:
rep
注意,f()
的优化实际上做了您最初写的事情:它实际上是将条件的值添加到n
。当然这是在c++中。如果没有bool
类型,看看C编译器会怎么做会很有趣。
另一个注意,因为你也标记了这个C:在C中,如果你不使用bool(来自<stdbool.h>
),而是使用int
s,那么一个版本相对于另一个版本的优势就消失了,因为两个版本现在都必须做一些测试。
这取决于你的编译器,你使用的优化选项和它的优化启发式。此外,在某些体系结构上,为了避免添加0,添加可能比执行条件跳转更快。
编译器不会优化掉+0,除非右边的表达式是一个编译器const值等于0。但是,在所有现代处理器上,添加0比尝试避免添加的分支(如果有的话)要快得多。因此,编译器最终在给定情况下做了最聪明的事情-简单地添加0。
有些人很聪明,有些人不够聪明。它高度依赖于优化器的实现。优化器也可能确定if
比+
慢,所以它仍然会执行加法。
- Adding MAKEFLAGS from MPC(The Makefile, Project, and Workspa
- 共享对象"Adding"函数?
- QCustomPlot adding QCustomItemText
- Adding dlib to C++ eclipse
- Qt adding library gstreamer-1.0
- 将专用基指针强制转换为专用于其他模板参数的派生指针("adding on"专用化)
- Adding QListWidgetItem To QListWidget
- Adding CCPoint to CCArray
- C/C++: adding 0
- Adding a library