作者yam276 (史萊哲林的優等生)
標題[閒聊] 每日C++小秘密(3):Copy Elision 與 RVO
時間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语
句返回。
--
※ 發信站: 批踢踢實業坊(ptt-club.com.tw), 來自: 114.32.48.170 (臺灣)
※ 文章網址: https://ptt-club.com.tw/Marginalman/M.1730197166.A.B21
推 DJYOMIYAHINA: 剩我都直接return整坨了 10/29 18:22