C ++ References and Return Values

I understand that the main point of the link is to avoid making copies of large structures, but what if the function you write creates a large structure? Is it less efficient (or are you more likely to run out of memory) to create a variable locally and then return it than pass the target as a reference and populate it from a function?

I can't seem so good, so a concrete example: suppose a function takes a string and returns the vector of each line in the line. Is there a significant advantage to the function:

void getLines(std::string in, std::vector<std::string>& out); 

above

 std::vector<std::string> getLines(std::string in); 

Thanks for any help, Wyatt

+6
c ++ performance memory-management
source share
4 answers

The first example should rather look like one of the following:

 void getLines(std::string in, std::vector<std::string> &out); void getLines(std::string in, std::vector<std::string> *out); 

The second style is often more convenient and theoretically can be done basically as effectively as the first:

http://en.wikipedia.org/wiki/Return_value_optimization

As far as this is seen in practice, it depends on the compiler, optimization levels and whether the compiler can detect this feature in the first place.

Until I speak for everyone, I have never managed to get compilers to use RVO, even with simple objects that do nothing. Therefore, I therefore personally recommend the first approach, because you are guaranteed to get the desired behavior on each compiler and (which is important to me ...) for each programmer code, i.e. So that the object created to save the return value is filled directly with the function being called without any additional copies.

(The cost of creating a default result object that could be avoided was the RVO to be used, usually low compared to a copy that could not be avoided by the compiler.)

Another point that should be noted is that if you try to avoid unnecessary copies, passing objects via a const reference instead of a value is often a good idea, for example:

 void getLines(const std::string &in, std::vector<std::string> &out); void getLines(const std::string &in, std::vector<std::string> *out); 
+5
source share

It depends on whether your compiler supports return value optimization (in most cases), and if the code is suitable for this optimization.

+5
source share

Well, in your particular case (filling the container with values) I would go to the input of the input iterator. But in all other cases (for example, in complex string generation or some calculations), I would be uninterested if you achieved the performance and trust of RVO (see Jim's answer) and the compiler to optimize it as it should. If this becomes a bottleneck (profile!), Change it, of course!

+1
source share

My advice is to write code so that the use of the client is as intuitive as possible.

If - as usual, you think that to return by value, then if your system has critical criticality and you find that a specific return value is not optimized by your compiler, even with the highest reasonable level of optimization , you can use some either appropriate command-line options or compiler hints when reaching RVO and, if necessary, taking into account alternative compilers - ideally - a C ++ 11 compiler that benefits from the always efficient move semantics , only then change the specific problem spot to accept the return value by reference.

+1
source share

All Articles