当实际使用该返回值时,我如何只支付函数创建的返回值的成本?

时间:2013-12-12 10:21:04

标签: c++ function optimization c++11 return-value

我常常看到变换器函数通过引用获取参数,并且还返回与函数返回值相同的参数。

例如:

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);
}

构造函数几乎可以执行任何操作,虽然不使用返回类型,但这并不意味着避免创建类型是安全的。但是,在这种情况下,当不使用函数的返回值时,不创建类型将是有利的。

是否有某种方式通知编译器如果没有使用返回类型,那么避免创建类型是安全的吗?这将是功能特定的,是程序员的决定;不是编译器可以自己解决的问题。

2 个答案:

答案 0 :(得分:0)

function的情况下,如果函数没有内联might not optimize it since it has non trivial constructor。但是,如果函数是内联的,它可能会优化未使用的返回类,如果它的生命周期不影响任何参数。此外,由于元组是标准类型,我相信大多数编译器将优化返回的变量。

答案 1 :(得分:0)

通常,编译器有两种优化代码的方法:

  1. (已命名)返回值优化(RVO / NRVO)
  2. R值参考
  3. 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,然后返回。在人工优化版本bar中,a会被传入,修改并提供给来电者。

    显然,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也有一些限制)因此,如果您关心性能,请使用参考传递。