[闲聊] 每日C++小秘密(3):Copy Elision 与 RVO

楼主: yam276 ('_')   2024-10-29 18:19:24
他们是什么?
Copy Elision 和 Return Value Optimization(RVO)是编译器的最佳化技术,
它们的目标是减少不必要的物件建构和拷贝,以提升程式效能。
Copy Elision
Copy Elision 是C++标准允许的最佳化手段,
避免了多次呼叫拷贝建构函式(或移动建构式)。
有些情况下编译器甚至会跳过呼叫任何建构式,
而是直接在目标位置上建构物件。
RVO (Return value optimization)
RVO 是Copy Elision的一个特例。
当函式回传 Local 物件时,
RVO 允许直接在呼叫者的内存空间建构物件,
而不是先在函式内建构,然后再拷贝到呼叫者。
原因
C++ 里面一个物件都会有以下成员:
建构式 (Constructor)
复制建构式 (Copy Constructor)
移动建构式 (Move Constructor)
解构式 (Destructor)
没有RVO的情况,可能在回传物件的过程会呼叫非常多次的各种建构式解构式,
造成资源的浪费。
Code:
#include <iostream>
class A {
public:
A() { std::cout << "Constructor\n"; }
A(const A&) { std::cout << "Copy Constructor\n"; }
A(A&&) { std::cout << "Move Constructor\n"; }
~A() { std::cout << "Destructor\n"; }
};
A func() {
A a; // 在此地建构物件a
return a; // 触发RVO,直接将a建构在呼叫者的内存中
}
int main() {
A b = func(); // 若RVO启用,不会有多余的拷贝或移动操作
return 0;
}
若启用了RVO:
Constructor
Destructor
若RVO被关闭:
Constructor
Copy Constructor (或 Move Constructor)
Destructor
Destructor
而在Modern C++,自C++17起,RVO变得强制性(Mandatory RVO),
编译器在大部分情况下必须强制进行RVO。
但RVO,真的好吗?
我在这边引用一段话CSDN看到的结论:
尽管C++11以上标准提出“复制省略(copy elision)”优化策略,并且GCC等主流编译器均
支持该优化,但我强烈不建议使用该技术。
我们在使用C++语言时,必须牢记,返回值必须是int、bool、枚举或指针等轻量级原生
(lightweight primitive)数据类型。
如果确实需要返回大型数据,请使用引用或指针作为输出参数返回,而不是通过return语
句返回。
作者: DJYOMIYAHINA (通通打死)   2024-10-29 18:22:00
剩我都直接return整坨了

Links booklink

Contact Us: admin [ a t ] ucptt.com