C 中的RVO和NRVO優化

2021-08-20 03:25:07 字數 1976 閱讀 3967

rvo (return value optimization) 和nrvo (named return value optimization) 是c++在處理乙個函式返回類物件並將返回值賦給另乙個物件時,為了減少拷貝構造次數以及析構次數而採用的一種編譯器優化技術。

本篇部落格以《深度探索c++物件模型》中例子來總結這兩種優化技術。**片段如下:

class point3d

cout << "operator="

}}point3d factory()

int main()

這個例子中的point3d類中顯式定義了建構函式、拷貝建構函式、析構函式以及過載了賦值運算子,並在內部加入了一些列印資訊來檢視這些函式的呼叫情況。

1)不做任何返回值優化。在g++中有乙個選項-fno-elide-constructors可以去掉任何返回值優化。最終列印情況如下:

constructor      //factory函式中構造po物件

copy

constructor //factory函式中用po物件拷貝構造臨時物件_temp

deconstructor //factory函式中返回時,析構掉區域性物件po

copy

constructor //main函式中用factory函式中拷貝構造的臨時物件拷貝構造物件p

deconstructor //析構臨時物件_temp

deconstructor //main函式結束時,析構物件p

可以看出,不做任何優化的話就是有兩次拷貝構造和析構,對照注釋很容易理解

2)做rvo優化,vs在debug模式下使用rvo而不用nrvo。對應的輸出如下:

constructor

copy

constructor

deconstructor

deconstructor //main函式中p的析構

在《在深度探索c++物件模型》書中,對應的解釋為,編譯器將factor函式改寫為了如下的偽**形式:

factory(const point3d &_result)

而main函式中賦值語句改寫為:

point3d p;

factory(p);

這樣將p直接做為引數,在factory()函式中進行構造,就不需要先將po拷貝構造出臨時物件_temp,再析構_temp。

3)那能不能直接構造p,而不需要先構造po,再拷貝構造p呢。答案是可以的,需要將factory()函式改寫為如下形式:

factor()

這種返回臨時物件的寫法,如果開啟了編譯器的rvo優化,factory()函式的大致偽**實現就會改寫為:

factory(const point3d &_result)

相應的列印情況,就為:

constructor    //p的構造

deconstructor //p的析構

這樣將拷貝建構函式和析構函式又減少了一次。

4)有時程式設計師會不注意將factory()函式改寫為(3)中的形式,那能不能不改寫也能起到(3)中的優化效果呢,這時nrvo優化就上場了。

如果程式設計師還是將factory()函式寫成:

point3d factory()

有了nrvo優化編譯器還是會將其優化成(3)中的形式,對應輸出結果當然同樣只有一次構造和析構。

我在vs下和gcc下分別在debug模式和release模式下驗證發現,gcc在debug和release模式下都支援nrvo優化,在vs的debug模式下只支援rvo優化,release模式下支援nrvo優化。對於其它的編譯器,還暫時沒做相應的驗證。

C 中的RVO優化和NRVO優化

rvo return value optimization 和nrvo named return value optimization 是c 在處理乙個函式返回類物件並將返回值賦給另乙個物件時,為了減少拷貝構造次數以及析構次數而採用的一種編譯器優化技術。本篇部落格以 深度探索c 物件模型 中例子來總...

C 中 NRVO優化與RVO優化

rvo return value optimization 和nrvo named return value optimization 是c 在處理 返回乙個class object的函式 時常用的優化技術,主要作用就是消除臨時物件的構造和析構成本。目前我正在研究 深度探索c 物件模型 對於這兩種常...

編譯器優化RVO和NRVO

編譯器選擇 如果想自己實踐rvo和nrvo,不要在vs下嘗試 這裡的vs不是指vs code 用支援g 的編譯器去測試 我這裡用的是mingw 因為vs無論在debug還是release下都是無法關閉rvo優化的,dubug下可以關閉nrvo優化。而g 預設都是執行nrv0優化的。rvo nrvo ...