代码之家  ›  专栏  ›  技术社区  ›  StackedCrooked

喜欢被命名的RVO?

  •  3
  • StackedCrooked  · 技术社区  · 15 年前

    我有这样一个函数:

    // Fetch 1 MB of data
    void GetData(std::vector<char> & outData);
    

    1MB是夸张的,但我想强调的是,最好避免不必要的拷贝。

    如果我加上这个超负荷:

    std::vector<char> GetData()
    {
        std::vector<char> result;
        GetData(result);
        return result;
    }
    

    那么,RVO有多可能介入?

    5 回复  |  直到 14 年前
        1
  •  7
  •   Jerry Coffin    15 年前

    对于最新的编译器(例如,vs 2005或更新版本,gcc 3.4或更新版本),基本上是确定的。我只说“大多数”,因为我没有测试现有的所有编译器。我在过去5年左右的时间里看过的每一个新编译器都包含了它。

        2
  •  3
  •   AnT stands with Russia    15 年前

    RVO很可能会启动,因为它是一个非常简单的优化,已经有一段时间了。但是,为了让这段代码在中等性能的代码中具有实际的实用价值,您需要nrvo。NRVO比较难被发现,因为它是相对新的。但是它是可用的。例如,MS编译器自VS2005以来就实现了它。

        3
  •  2
  •   Mark B    15 年前

    我不认为有任何标准的答案:这取决于你的编译器和它的能力。

    如果您考虑实现这一点是为了方便,那么为什么不试着使用编译器,查看程序集或对其进行概要分析,看看会发生什么?关于编译器实际执行操作的经验证据可能比猜测某些编译器可能执行或不执行的操作要好。

        4
  •  0
  •   Dummy00001    15 年前

    那么,RVO有多可能介入?

    思考是软件开发人员的工作,而不是编译器的工作。

    编译器通常经过优化以使好的代码能够正常工作,而不是坏的代码。

    就我个人而言,我使用第一种形式。通常使用指针而不是引用来突出显示参数是输出参数而不是输入参数的事实。

        5
  •  0
  •   James Curran    15 年前

    另外,当你说:

    std::vector<char> GetData() 
    { 
    //   :
        return result; 
    }
    
    vector<char> x = GetData();
    

    在被叫者中, result 复制到“返回值”,然后在调用方中,将“返回值”复制到 x . NRVO可以删除其中一个副本,但不能同时删除这两个副本。编译器必须至少调用一次copy ctor,因为它必须假定copy ctor具有必须执行的副作用。