C++编译器优化之RVO
2020-09-05 18:22
633 查看
写这篇文章纯属意外收获.
先看一段代码:
在这段代码中定义了构造函数,拷贝构造函数,移动构造函数,赋值构造,移动赋值构造,以及析构函数.
#include <iostream> using namespace std; class A { public: A() { cout << "constructor\n" <<flush; } A(const A &a) { cout << "copy constructor\n"<<flush; } A(A &&a) { cout << "move constructor\n" <<flush; } A &operator=(const A &a) { cout << "copy assignment constructor\n" <<flush; if (this == &a) { return *this; } else { this->i = a.i; } return *this; } A &operator=(A &&a) { cout << "move assignment constructor\n" <<flush; return *this; } ~A(){ cout<<"destructor\n"<<flush;} private: int i; }; inline A foo(){ return A(); } int main() { auto x=foo(); return 0; }
此处在以前我可能会分析这段代码效率会很低,调用了1次构造函数,2次移动拷贝构造函数,三次析构函数.
具体流程为,
-
1.执行foo函数,
return A();
2.A()
调用构造函数生成中间对象(是一个右值),
3.执行移动构造函数生成返回值,
4.析构中间对象
5.调用移动构造函数生成x对象
6.析构返回值对象
7.析构x对象,程序结束.
Maybe,部分人还有其他答案,但是把这段代码编译执行看看结果呢?
➜ g++ main.cpp -std=c++11 ➜ ./a.out constructor destructor
哈哈,**居然只调用了一次构造,一次析构?**是我错了?居然比我想想的简单高校很多,这是为何
程序逻辑上来说,上面的几次构造与析构没问题,只是编译的时候编译器进行了RVO优化.换一种编译方式可验证我们的分析
➜ g++ main.cpp -std=c++11 -fno-elide-constructors ➜ ./a.out constructor move constructor destructor move constructor destructor move constructor destructor destructor
何谓RVO优化
RVO 即 “Return Value Optimization”,是一种编译器优化技术,通过该技术编译器可以减少函数返回时生成临时值值(对象)的个数,可以提高程序的运行效率,对需要分配大量内存的类对象其值复制过程十分友好。
在 C++11 标准中我们可以看到关于该优化标准的更多信息。标准中规定,在以下两种环境下,要求编译器省略类对象的复制和移动构造,即使复制/移动构造函数和析构函数拥有可观察副作用。RVO优化直接将对象构造到它们本来要复制/移动到的存储中。只要语言确保不发生复制/移动操作,复制/移动构造函数就不必存在或可访问,即使在概念上。这两种环境分别是:
- 在 “return” 语句中,当操作数为与函数返回类型为同一类类型的纯右值时;
- 在变量的初始化中,当初始化器表达式为与变量类型为同一类类型的纯右值时:
相关文章推荐
- C++编译器的递归深度与程序优化思考
- 阐述C++编译器变量进行优化说明
- C++编译器优化-返回值优化
- C++编译器优化:Copy Elision
- C++函数返回临时对象优化问题/RVO/NRVO
- 由一道题目想到的C++编译器优化问题
- 轻松搞死VS2008的C++编译器,error PRJ0002,优化编译器遇到问题需要关闭
- C++编译器到底能帮我们把代码优化到什么程度?
- 编译器自动优化——为什么我的C++编译器不调用拷贝构造函数了?
- C++编译器到底能帮我们把代码优化到什么程度?
- C++编译优化之RVO(Return Value Optimization) &&C++直接初始化与赋值初始化的区别
- 通过一道面试题来看 C++的RVO 优化
- C++编译器到底能帮我们把代码优化到什么程度?
- C++编译器优化:Copy Elision(省略不必要的拷贝)
- C++编译器到底能帮我们把代码优化到什么程度?
- C++中的RVO与NVR优化
- 右值引用、左值引用、指针、RVO优化
- EBO,c++编译器有empty继承优化(编译期)
- 插入排序的实现与优化并和选择排序进行性能比较
- CSAPP:代码优化【矩阵读写】