算术运算器速度
Arithmetic operator speed
以下语句在性能方面基本相同吗?
a = a / 10;
或
a /= 10;
这取决于-对于基本类型,任何编译器都应该为两者生成相同的代码。
对于用户定义的类型,您可以重载两个运算符来做不同的事情(请不要),这完全取决于它们的实现方式。
让我们进行小测试。我使用的是gcc版本4.7.3
我期望a /= 10
等于a = a / 10
。我们可以通过使用-S
参数将代码编译为asm来检查它
int main() {
int a;
a = a / 10;
}
将给出
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl -4(%rbp), %ecx
movl $1717986919, %edx
movl %ecx, %eax
imull %edx
sarl $2, %edx
movl %ecx, %eax
sarl $31, %eax
movl %edx, %ecx
subl %eax, %ecx
movl %ecx, %eax
movl %eax, -4(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
和
int main() {
int a;
a /= 10;
}
给出相同的输出
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl -4(%rbp), %ecx
movl $1717986919, %edx
movl %ecx, %eax
imull %edx
sarl $2, %edx
movl %ecx, %eax
sarl $31, %eax
movl %edx, %ecx
subl %eax, %ecx
movl %ecx, %eax
movl %eax, -4(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
总之,短运算运算符的区别仅在于可读性,而仅限于基元运算符。不同性能的一个很好的例子是迭代器的预创建和后创建
这取决于编译器。可以猜测,大多数编译器将从两条指令生成相同的代码。
试着对这些代码进行基准测试,或者查看汇编代码,在每种情况下都会生成什么代码。
例如,Microsoft Visual Studio 2013处于调试模式:
i = i / 20;
011F43C5 mov eax,dword ptr [i]
011F43C8 cdq
011F43C9 mov ecx,14h
011F43CE idiv eax,ecx
011F43D0 mov dword ptr [i],eax
i /= 20;
011F43D3 mov eax,dword ptr [i]
011F43D6 cdq
011F43D7 mov ecx,14h
011F43DC idiv eax,ecx
011F43DE mov dword ptr [i],eax
不过,如果我们谈论的是用户类型,情况会发生变化,因为您可以为这两个运算符实现不同的算法。在这种情况下,性能严格取决于具体的实现。
在一般情况下,第二个例子总是更可取的。
原因很简单。
对于除内部数据类型之外的任何类型,运算符/都将(当然应该!)以运算符/=的形式实现。
这是因为操作符/获取一个副本,应用操作符/=(Don't Repeat Yourself),然后返回该副本。
a /= 10;
归结为
- 呼叫接线员/=
而
a = a / 10;
归结为:
- 呼叫上的操作员/,该操作员:
- 调用复制构造函数
- 呼叫副本上的操作员/=
- 调用赋值运算符将返回的副本赋值到
你通常会看到运营商这样声明:
class A {
...
public:
A& operator/=(double rhs) {
_internalThing /= rhs;
return *this;
}
private:
double _internalThing;
};
// binary operators should be free functions
A operator/(A lhs, double rhs) {
lhs /= rhs;
return lhs;
}
相关文章:
- 为什么在读取文件大小时文件IO速度会发生变化
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 文件系统:复制功能的速度秘诀是什么
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 两个连续的 OpenMP 并行区域会相互减慢速度
- 查找标准::hash_map与标准::矢量的速度
- 加快在C++中读取/处理日志文件的速度
- 为什么这些算法的运行速度比它们应该的要快?
- 如何提高文件的读取速度?
- 通过libpqxx提高PostgreSQL数据库的更新速度
- 使用 IMFSinkWriter 编码的视频的播放速度会根据宽度而变化
- 计算车辆之间的距离并设置速度,使距离保持不变,例如 5 米
- 如何加快大字符串的解析速度?
- 如何比较两个函数的速度和性能
- 线程相互减慢速度
- 多线程减慢程序速度:无错误共享,无互斥锁,无缓存未命中,无小工作量
- 使用 Unity 构建加快C++构建速度,并减少标头依赖项
- 从 OpenCV 3 切换到 OpenCV 4 会导致网络摄像头以最大 5 fps 的速度录制,而不是通常的 30 f
- 算术运算器速度