为什么后缀增量比C 中的前缀更快
Why is the postfix increment faster than the prefix one in the C++?
我一直认为必须相反。但是,当我尝试此简单代码时,我得到了意外的结果:
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <chrono>
using namespace std;
int main(int argc, char* argv[])
{
int x = 0, y = 0;
double z;
chrono::steady_clock::time_point start_point;
start_point = chrono::steady_clock::now();
for(int i = 0; i < 100000; x = ++i)
for(int j = 0; j < 100000; y = ++j)
z = static_cast<double>(x * y);
cout << "The prefix increment took a " << chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_point).count() << " milliseconds" << endl;
start_point = chrono::steady_clock::now();
for(int i = 0; i < 100000; x = i++)
for(int j = 0; j < 100000; y = j++)
z = static_cast<double>(x * y);
cout << "The postfix increment took a " << chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_point).count() << " milliseconds" << endl;
// To make the compiler happy...
x = y = static_cast<int>(z / z);
cout << "SUCCESS" << endl;
return EXIT_SUCCESS;
}
在我的计算机上运行此代码的结果是:
The prefix increment took a 25716 milliseconds
The postfix increment took a 19119 milliseconds
SUCCESS
编辑:
是的,将z = ...
更改为z += ...
导致执行时间相等。
所以谢谢大家的回答。
根本没有差异 - 任何可感知的差异都是由于您的测试技术引入的伪影引起的。
编译器多年来一直在优化i++
(尽管我仍然出于习惯使用++i
(。不要测试这样的事情 - 设置框架太难了。琐碎程序并改用生成的程序集。
还请注意,在具有32位int
的平台上(非常常见(,由于int
溢出,您的代码行为不确定(100,000
平方大于31 st 2的功率(。这使您的测试完全毫无用处。
仅在巴希巴已经说过的内容中添加少量
int i;
i++
和
int i;
++i
被编译为
push rbp
mov rbp, rsp
add DWORD PTR [rbp-4], 1
重要的线增加值是
add DWORD PTR [rbp-4], 1
^^^ ^^^
relevant parts
在回答有关优化的评论时,上面的代码具有优化 off ;使用-O
导致
add DWORD PTR [rdi], 1
^^^ ^^^
relevant parts
i++
和++i
。我必须将样本调整为
void F(int& i)
{
++i; // respectively i++
}
使其不能完全优化,但要点仍然相同。
我使用了gcc 7.3 x86-64
。使用在线编译器资源管理器自己对其进行测试。
相关文章:
- 高效的字符串截断算法,按顺序删除相等的前缀和后缀
- 为什么 C++ 程序员更喜欢前缀 ++,而 Java 程序员更喜欢后缀 ++?
- 导致错误的后缀和前缀增量
- 为什么后缀增量比C 中的前缀更快
- C++编译器如何扩展前缀和后缀运算符++()?
- 指向重载前缀和后缀运算符中的类对象的指针
- C++如何知道在重载运算符时增量++是前缀或后缀
- 在一行C 中,该代码后缀和前缀的输出的逻辑是什么
- Android Cmake编译器正在生成带有额外前缀和符号后缀的.out文件
- 为什么后缀失败并且前缀在传递迭代器作为参数并在尾部位置递归时工作正常
- std::map<tuple<int,int>.lower_bound/upper_bound 前缀搜索,而不找到后缀的最小/最大元素
- 在迭代器上澄清后缀/前缀操作员
- 前缀和后缀运算符 C++
- 在哪里可以找到C++11类型前缀/后缀的列表
- 编译器如何翻译后缀/前缀运算符
- 为什么所有type_traits类都必须使用 'typename' 和'::type'前缀/后缀调用?
- 涡轮增压C++(非可视)(后缀和前缀运算符)
- ++ 后缀和前缀的起源
- C++运算符重载前缀/后缀
- 预结束/追加(前缀/后缀)行在GVim