返回向量比通过引用传递慢吗?
Is returning a vector slower than passing by reference?
在过去,我们被训练使用通过引用传递的结果参数,以避免不必要地复制数据。
然而,对于更智能的编译器——尤其是 C++11 的扩展,是否仍然需要?
具体来说,现代 C++11/C++14 编译器在 2018 年是否有任何理由(仍然)使用
void Filter(vector<CObject*> &elements, vector<CObject*> &outElements);
而不是简单地返回向量,即
vector<CObject*> Filter(vector<CObject*> &elements);
提前感谢所有见解!
and particular the extensions to C++11 is this still required?
没有。在最好的情况下,RVO (return 值优化) 将启动,这将完全消除任何 copy/move.
在最坏的情况下,对象将被移出函数。 std::vector
的移动非常便宜(与仅几次指针交换相比)。
这是因为表达式 Filter(some_input)
是类型 std::vector<CObject*>
的 rvalue,并且 std::vector
的构造函数有一个重载接受一个右值引用:see (6) here.
当您从函数中 return 取值时,编译器会应用 Return 值优化来避免复制。
因此,这两种情况都是相似的。
您可以阅读更多 there.
In the old days we were trained to use result parameters passed by reference in order to avoid unnecessarily copying data around.
实际上,即使在使用旧的 C++ 编译器时,这也是一个非常糟糕的建议:首先是为了清晰,其次是为了效率。
特别是,通过引用值返回可防止在调用者中生成值 const
(这提高了清晰度 并且 提供了其他优化机会)。
当然,如果分析显示这是一个性能瓶颈,那么就必须进行必要的更改。使用 RVO 和 NRVO(现在很常见),并将语义作为 back-up 移动,现在不太可能成为性能瓶颈。
在过去,我们被训练使用通过引用传递的结果参数,以避免不必要地复制数据。
然而,对于更智能的编译器——尤其是 C++11 的扩展,是否仍然需要?
具体来说,现代 C++11/C++14 编译器在 2018 年是否有任何理由(仍然)使用
void Filter(vector<CObject*> &elements, vector<CObject*> &outElements);
而不是简单地返回向量,即
vector<CObject*> Filter(vector<CObject*> &elements);
提前感谢所有见解!
and particular the extensions to C++11 is this still required?
没有。在最好的情况下,RVO (return 值优化) 将启动,这将完全消除任何 copy/move.
在最坏的情况下,对象将被移出函数。 std::vector
的移动非常便宜(与仅几次指针交换相比)。
这是因为表达式 Filter(some_input)
是类型 std::vector<CObject*>
的 rvalue,并且 std::vector
的构造函数有一个重载接受一个右值引用:see (6) here.
当您从函数中 return 取值时,编译器会应用 Return 值优化来避免复制。 因此,这两种情况都是相似的。 您可以阅读更多 there.
In the old days we were trained to use result parameters passed by reference in order to avoid unnecessarily copying data around.
实际上,即使在使用旧的 C++ 编译器时,这也是一个非常糟糕的建议:首先是为了清晰,其次是为了效率。
特别是,通过引用值返回可防止在调用者中生成值 const
(这提高了清晰度 并且 提供了其他优化机会)。
当然,如果分析显示这是一个性能瓶颈,那么就必须进行必要的更改。使用 RVO 和 NRVO(现在很常见),并将语义作为 back-up 移动,现在不太可能成为性能瓶颈。