RVO和NRVO介绍
前言
半年前就想写一篇关于RVO
和NRVO
的介绍,但碍于没什么时间去写博客。在跟身边人进行学术探讨的时候,会发现部分人可能尝到了编译器给它做返回值优化的好处,知道这段代码被优化了,但为什么 如何去做,却不知道。
因此,为了尝试说明RVO
和NRVO
的好处、使用场景、局限性等,在看了数个StackOverflow的讨论之后,有了这篇博客。
RVO(返回值优化(Return Value Optimization))
- 如果函数返回一个无名的临时对象,该对象将被编译器移动或拷贝到目标中,在此时,编译器可以优化代码以减少对象的构造,即省略拷贝或移动。
T f() {
return T();
}
f(); // 只有一次对T的默认构造函数的调用
NRVO(命名返回值优化(Named Return Value Optimization))
- 命名返回值优化(指的是省略了命名对象的拷贝这一事实)
- 如果函数按值返回一个类的类型,并且返回语句的表达式是一个具有自动存储期限的非易失性对象的名称(即不是一个函数参数),那么可以省略优化编译器所要进行的拷贝/移动。如果是这样的话,返回值就会直接构建在函数的返回值所要移动或拷贝的存储器(即被拷贝省略优化掉的拷贝或移动的存储器)中。
注意,NRVO
不会应用于函数参数;它仅适用不是函数参数的局部变量,拿以下代码进行分析
#include <stdio.h>
class Data {
public:
Data() {
printf("I am in constructor\n"); }
Data(const Data &data) {
printf("I am in copy constructor\n"); }
~Data() {
printf("I am in destructor\n"); }
int mem_var;
};
Data process(int i) {
Data data;
data.mem_var = i;
return data;
}
Data process1(Data data){
return data;
}
int main() {
printf("process\n");
Data data;
data