簡體   English   中英

實際使用該返回值時,如何僅支付該函數創建的返回值的成本?

[英]How do I only pay the cost of a function's created return value, when that return value is actually used?

通常,我看到轉換器函數將按引用獲取參數,並且還返回與函數的返回值相同的參數。

例如:

std::string& Lowercase(std::string & str){
    std::transform(str.begin(), str.end(), str.begin(), ::tolower);
    return str;
}

我知道這樣做是為了方便,而且我的印象是,編譯器將針對實際未使用返回值的情況進行優化。 但是,我不相信編譯器可以針對非基本類型的新創建的返回值進行優化。 例如:

std::tuple<int,std::string,float> function(int const& num, std::string const& str, float const& f){

    return std::tuple<int,std::string,float>(num,str,f);
}

構造函數幾乎可以做任何事情,盡管不使用返回類型,但這並不意味着避免創建該類型是安全的。 但是,在這種情況下,當不使用函數的返回值時不創建類型將是有利的。

是否可以通過某種方式通知編譯器,如果未使用返回類型,則可以避免創建該類型嗎? 這將是特定於功能的,並且是程序員的決定; 編譯器無法自行解決的問題。

對於function ,如果函數沒有內聯,則它可能無法優化它,因為它具有非平凡的構造函數 但是,如果函數是內聯的,則在其生命周期不影響任何參數的情況下,它可能會優化未使用的返回類。 另外,由於元組是標准類型,我相信大多數編譯器都會優化返回的變量。

通常,編譯器可以通過兩種方式優化代碼:

  1. (命名)返回值優化(RVO / NRVO)
  2. R值參考

RVO

以下面的代碼為例:

struct A {
    int v;
};

A foo(int v) {
    A a;
    a.v = v;
    return a;
}

void bar(A& a, int v) {
    a.v = v;
}

A f;
f = foo(1);

A b;
bar(b, 1);

在函數foo ,將構造變量a ,修改其成員v並返回。 在人為優化的版本bara會傳入,修改並提供給調用者。

顯然, fb是相同的。

而且,如果您了解更多有關C ++的知識,您將知道從foo返回時,結果a被復制到外部f ,並且將調用a的dtor。

使優化的foo成為bar方法稱為RVO ,它省略了內部a到外部f的副本。 修改直接轉到調用方的變量。

請當心,在某些情況下RVO將不適用:復制ctor具有副作用,多次退貨等。

這是詳細的說明:
MSDN
CppWiki

價值

優化返回值的另一種方法是使用C ++ 11中引入的rvalue ctor 。通常來說,這就像調用std::swap(vector_lhs, vector_rhs)交換內部數據指針以避免深度復制。

這是一篇關於優化的很好的文章: http : //cpp-next.com/archive/2009/08/want-speed-pass-by-value/

最后但並非最不重要的

Going Native 2013中 ,Andrei Alexandrescu發表了有關如何編寫快速C ++代碼的演講。 通過引用傳遞比rvalue更快。 (RVO也有一些限制)因此,如果您確實關心性能,請使用通過引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM