Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is returning a vector slower than passing by reference?

In the old days we were trained to use result parameters passed by reference in order to avoid unnecessarily copying data around.

However with smarter compilers - and particular the extensions to C++11 is this still required?

Specifically, is there any reason in 2018 with modern C++11/C++14 compilers to (still) use

void Filter(vector<CObject*> &elements, vector<CObject*> &outElements);

instead of simply returning the vector, i.e.

vector<CObject*> Filter(vector<CObject*> &elements);

Thanks in advance for all insights!

like image 261
ATV Avatar asked Feb 16 '18 09:02

ATV


People also ask

Why is it best to pass a vector as a reference?

Passing by reference saves a lot of time and makes the implementation of the code faster. Note: If we do not want a function to modify a vector, we can pass it as a const reference also.

Should I pass vector by reference or value?

vector<int> is non-array, non-reference, and non-pointer - it is being passed by value, and hence it will call copy-constructor. So, you must use vector<int>& (preferably with const , if function isn't modifying it) to pass it as a reference.

Is returning a vector bad?

Yes, returning a reference to an element of a std::vector is safe, unless you change the number of elements in the container while holding on to the reference.

Which is generally more efficient a function that returns an object by reference or a function that returns an object by value?

Returning the object should be used in most cases because of an optimsation called copy elision. However, depending on how your function is intended to be used, it may be better to pass the object by reference.


2 Answers

and particular the extensions to C++11 is this still required?

No. In the best case scenario, RVO (return value optimization) will kick in, which will completely elide any copy/move.

In the worst case scenario, the object will be moved out of the function. Moves for std::vector are very cheap (comparable to just a few pointer swaps).

This is because the expression Filter(some_input) is an rvalue of type std::vector<CObject*>, and std::vector's constructor has an overload accepting an rvalue reference: see (6) here.

like image 56
Vittorio Romeo Avatar answered Nov 09 '22 22:11

Vittorio Romeo


In the old days we were trained to use result parameters passed by reference in order to avoid unnecessarily copying data around.

Actually, even when one was using an old C++ compiler this was pretty poor advice: write for clarity first and efficiency second.

In particular, returning by a reference value prevents making the values in the caller const (which improves clarity and provides other optimization opportunity).

Of course, if profiling shows this was a performance bottleneck, then one had to make the necessary changes. With RVO and NRVO (which are now pretty common), and move semantics as a back-up it is now very unlikely to be a performance bottleneck.

like image 43
Martin Bonner supports Monica Avatar answered Nov 09 '22 22:11

Martin Bonner supports Monica