Search code examples
c++performancestlc++11

Efficiency of output parameter vs return value on the stack for stl data structures


lets say I have the functions

std::Vector<Point> calculate() {
   std::Vector<Point> points; //do stuff with points
   return points;
}

and

void calculate(std::Vector<Point>& points) {
   //do stuff with points
}

So my question is specific to objects initialized on the stack, and are stl objects. Is there any difference in performance, and what is the popular method of doing it

regards


Solution

  • Taking the value as a reference parameter has the following properties:

    1. No copying, moving, or any other operation will be done.
    2. The return value cannot be immediately discarded on the user's side. They can't just shove a temporary at your function's reference parameter or something. They must declare a variable, and therefore they must give it a name which will live within the current scope.
    3. The API suggests that the value is an input/output parameter. That is, there is a value being passed in which will be read and written. If that is not the case, then using it represents a sub-optimal API design element.

    Returning the value has the following properties:

    1. If copy elision is not available (either due to the nature of the function's implementation, a poor compiler, or that the return value is not initializing a new value), then the return value will be moved. Not copied. Movement is not free, but generally it is not much more expensive than a few pointer copies. No new objects or memory will be allocated or deallocated.
    2. The API enforces the output nature of the value. There is no way for the user to play with the output it passes in because it doesn't pass anything in. Similarly, there is no way for the function to read any values because it doesn't take anything in. It is an output value, period; the function generates it and returns it.
    3. The return value can be discarded immediately at the user's discretion. Obviously if users are doing this a lot, it suggests that something is wrong, but it is up to the user to decide if they want to keep the output value or not. The C++17 [[nodiscard]] attribute can be used in cases where discarding the value is categorically incorrect.