When returning a value, the compiler probably creates a temp variable and then set the value original object (i.e. if c = a + b, then c is original return variable).
If we developed 2 version of as the following:
The second version, without RVO, executed in 1.89 seconds. The first version, with RVO applied was much faster—1.30 seconds.
We speculated that the difference may lie in the fact that Version 1 used a named variable (retVal) as a return value whereas Version 2 used an unnamed variable. Version 2 used a constructor call in the return statement but never named it. It may be the case that this particular compiler implementation chose to avoid optimizing away named variables.
In addition, you must also define a copy constructor to “turn on” the Return Value Optimization. If the class involved does not have a copy constructor defined, the RVO is quietly turned off.
If the compiler can’t do RVO you can make iy through computational constructor:
You can now (after declaring the preceding computational constructor) use the following operator overloading guaranteeing RVO:
If you wanted to apply the same idea to the other arithmetic operators, you would have to add a third argument to distinguish the signatures of the computational constructors for addition, subtraction, multiplication, and division. This is the criticism against the computational constructor: It bends over backwards for the sake of efficiency and introduces “unnatural” constructors.
- If you must return an object by value, the Return Value Optimization will help performance by eliminating the need for creation and destruction of a local object.
- The application of the RVO is up to the discretion of the compiler implementation. You need to consult your compiler documentation or experiment to find if and when RVO is applied.
You will have a better shot at RVO by deploying the computational constructor.