C 命名返回值優化(NRVO)

2021-09-21 05:19:35 字數 4318 閱讀 1291

命名的返回值優化(nrvo),這優化了冗餘拷貝建構函式和析構函式呼叫,從而提高了總體效能。值得注意的是,這可能導致優化和非優化程式之間的不同行為。

下面是**段1中的乙個簡單示例,以說明優化及其實現方式:

a mymethod (b &var

)

使用上述函式的程式可能具有如下構造:

vala = mymethod(valb);
從mymethod返回的值是在vala通過使用隱藏的引數所指向的記憶體空間中建立的。下面是當我們公開隱藏的引數並顯示地顯示建構函式和析構函式時的功能:

a mymethod(a &_hiddenarg, b &var)

上段**為不使用nrvo的隱藏引數**(偽**)

從上面的**可以看出,有一些優化的機會。其基本思想是消除基於堆疊的臨時值(retval)並使用隱藏的引數。因此,這將消除基於堆疊的值的拷貝建構函式和析構函式。下面是基於nrvo的優化**:

a mymethod(a &_hiddenarg, b &var)

帶有nrvo的隱藏引數**(偽**)

**示例

示例1:簡單示例

#include

class

rvo rvo( const rvo& c_rvo )

~rvo()

int mem_var;

};rvo mymethod

(int i)

intmain

()

**:sample1.cpp

如果沒有nrvo,預期的輸出將是:

i am in constructor

i am in constructor

i am in

copy constructor

i am in destructor

i am in destructor

i am in destructor

使用nrvo,預期的輸出將是:

i am in constructor

i am in constructor

i am in destructor

i am in destructor

示例2:更複雜的示例

#include

class

a ~a()

a(const a& a)

int i, x, w;

};class

b ~b()

b(const b& b)

};a mymethod

()int

main

()

**sample2.cpp

無nrvo的輸出將如下所:

a: i am in constructor

a: i am in constructor

b: i am in constructor

a: i am in

copy constructor

b: i am in destructor

a: i am in destructor

a: i am in

copy constructor

a: i am in destructor

a: i am in destructor

a: i am in destructor

當nrvo優化啟動時,輸出將是:

a: i am in constructor

a: i am in constructor

b: i am in constructor

a: i am in

copy constructor

b: i am in destructor

a: i am in destructor

a: i am in destructor

a: i am in destructor

優化限制

有些情況下,優化不會真正啟動。以下是這些限制的樣本

示例3:異常示例

在遇到異常時,隱藏的引數必須在它正在替換的臨時範圍內被破壞。

// rvo class is defined above in figure 4

#include

rvo mymethod

(int i)

intmain

() catch(char* str)

**sample3.cpp

如果沒有nrvo,預期的輸出將是:

i am in constructor

i am in constructor

i am in destructor

i caught the exception

i am in destructor

如果「丟擲」被注釋掉,輸出將是:

i am in constructor

i am in constructor

i am in

copy constructor

i am in destructor

i am in destructor

i am in destructor

現在,如果「丟擲」被注釋掉,並且nrvo被觸發,輸出將如下所示:

i am in constructor

i am in constructor

i am in destructor

i am in destructor

也就是說sample3.cpp在沒有nrvo的情況下,會表現出相同的行為。

示例4:不同的命名物件示例

若要使用優化,所有退出路徑必須返回同一命名物件。

#include

class

rvo rvo(const rvo& c_rvo)

int mem_var;

};rvo mymethod

(int i)

intmain

()

**sample4.cpp

啟用優化時輸出與不啟用任何優化相同。nrvo實際上並不發生,因為並非所有返回都返回相同的物件。

i am in

constructor

i am in constructor

i am in copy constructor

如果將上面的示例更改為返回rvo。在返回物件時,優化將消除複製建構函式:

#include

class

rvo rvo(const rvo& c_rvo)

int mem_var;

};rvo mymethod

(int i)

intmain

()

**sample4_modified.cpp修改並使用nrvo,輸出結果將如下所示:

i am in

constructor

i am in constructor

優化***

程式設計師應該意識到這種優化可能會影響應用程式的流程。下面的示例說明了這種***:

#include

int numconscalls = 0;

int numcpyconscalls = 0;

class

rvo rvo(const rvo& c_rvo)

};rvo mymethod

()int

main

()

**段sample5.cpp

編譯未啟用優化將產生大多數使用者所期望的。「建構函式」被呼叫兩次。「拷貝建構函式」被呼叫一次。因此除法生成2。

constructor calls / copy constructor calls = 2
另一方面,如果上面的**通過啟用優化進行編譯,nrvo將會啟用。因此「拷貝建構函式」呼叫將被刪除。因此,numcpyconscalls將為零,導致異常。如果沒有適當處理,可以導致應用程式崩潰。

引入自:

C 返回值優化

當函式需要返回物件時,通常有兩種寫法,一種是直接在return語句中返回乙個物件,一種是先構造好乙個物件,然後在return中將其返回。以下 為例 include include using namespace std struct node node const node n name n.nam...

返回值優化

通過傳值方式返回要建立新物件時,應注意使用的形式,例如在operator return integer left.l right.l 咋看起來這像是乙個 對乙個建構函式的呼叫 其實並非如此。這是臨時物件語法,它是在說 建立乙個臨時integer物件並返回它 據此我們可能認為如果建立乙個有名字的區域性...

返回值優化

返回值優化,是一種屬於編譯器的技術,它通過轉換源 和物件的建立來加快源 的執行速度。rvo return value optimization。class complex 複數 complex const complex a real a.real imag a.imag complex opera...