C++之RVO返回值优化

简介: C++进阶之RVO

什么是RVO优化

RVO的全称是Return Value Optimization。RVO是一种编译器优化技术,可以把通过函数返回创建的临时对象给”去掉”,然后可以达到少调用拷贝构造的操作目的,
它是C++11标准的一部分。

如果编译器明确知道函数会返回哪一个局部对象,那么编译器会把存储这个局部对象的地址和存储返回值临时对象的地址进行复用,也就是说避免了从局部对象到临时对象的拷贝操作。这就是RVO。

main.cpp
#include <iostream>
using namespace std;
class A {
public:
    A() {
        cout << "构造函数" << endl;
    }

    A(const A &a) {
        cout << "拷贝构造函数" << endl;
    }

    ~A() {
        cout << "析构函数" << endl;
    }

};

A getA() {
    A a;
    return a;
}

int main() {
    A b = getA();
    return 0;
}

以上程序如果在C++11下编译,并且没有关闭RVO优化的话一般只会输出:

构造函数
析构函数

也就是仅仅发生了一次构造,连拷贝构造都没有发生,这就是编译器RVO优化所做的事情。

我们试下如果不使用RVO优化的话会是怎样的一个过程呢?对于以上程序我们用g++命令禁用掉RVO优化编译g++ main.cpp -o main -fno-elide-constructors,然后运行可执行文件main会发现输出如下:

构造函数
拷贝构造函数
析构函数
拷贝构造函数
析构函数
析构函数

天呐,我们发现一个简单的函数调用居然发生了三次构造,分别是一次普通构造和两次拷贝构造。首先在函数getA内部发生了一次普通的构造,然后在函数getA返回时将局部变量a拷贝给了函数getA的返回值作为临时变量,这里发生了第一次拷贝。
最后在函数main中将函数getA中返回的临时变量通过拷贝构造生成变量b,这里产生了第二次拷贝。

RVO诞生之前

通过对比我们发现RVO的存在实实在在的提高了我们程序的性能。那么在RVO诞生之前,程序员们一般是通过怎么方式减少拷贝呢?可以通过引用传参数的方式减少临时变量的拷贝,
也就是将你想要的结果的引用作为函数的参数传递到函数中去,然后在函数中给结果引用赋值,伪代码:

void getA(A &result) {
    A temp;
    result = temp;
}

在这里想说的是,新标准的诞生总是带着解决某个问题的目的而来,随着新标准的普及,我们应该紧跟发展的脚步,虽不能说做到形影不离,但也不能让自己落后得太远。

NRVO

NRVO其实就是RVO的一个变种或者是优化,理解了RVO也就理解了NRVO。。。

资料

更多资料可以参考 《More Effective C++》

条款 20:协助完成“返回值优化(RVO)”
目录
相关文章
|
存储 缓存 算法
【C/C++ 性能优化】提高C++程序的缓存命中率以优化性能
【C/C++ 性能优化】提高C++程序的缓存命中率以优化性能
1582 0
|
3月前
|
存储 算法 数据处理
公司局域网管理中的哈希表查找优化 C++ 算法探究
在数字化办公环境中,公司局域网管理至关重要。哈希表作为一种高效的数据结构,通过哈希函数将关键值(如IP地址、账号)映射到数组索引,实现快速的插入、删除与查找操作。例如,在员工登录验证和设备信息管理中,哈希表能显著提升效率,避免传统线性查找的低效问题。本文以C++为例,展示了哈希表在局域网管理中的具体应用,包括设备MAC地址与IP分配的存储与查询,并探讨了优化哈希函数和扩容策略,确保网络管理高效准确。
|
8月前
|
安全 编译器 程序员
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
137 2
|
8月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
276 6
|
8月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化2
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
119 6
|
8月前
|
安全 测试技术 C++
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化1
【C++篇】从零实现 C++ Vector:深度剖析 STL 的核心机制与优化
176 7
|
12月前
|
编译器 C++ 开发者
C++一分钟之-返回值优化与Move Semantics
【6月更文挑战第19天】C++的RVO与移动语义提升效率,减少对象复制。RVO是编译器优化,避免临时对象的创建。移动语义通过右值引用和`std::move`转移资源所有权。注意RVO不是总有效,不应过度依赖。使用移动语义时,避免误用`std::move`导致对象无效。示例展示了RVO和移动构造函数的应用。理解并恰当使用这些机制能写出更高效代码。
132 3
|
消息中间件 算法 Java
C++实时通信优化技术探究
C++实时通信优化技术探究
130 3
|
编译器 C++
【C++练级之路】【Lv.4】类和对象(下)(初始化列表,友元,static成员,编译器的优化)
【C++练级之路】【Lv.4】类和对象(下)(初始化列表,友元,static成员,编译器的优化)
|
4月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。