Question

I am trying to reduce the memory footprint of an application developed mostly in C++ and one the things I was looking into was returning a particularly large data structure by reference vs returning them by value. I needed some confirmation on it. For instance, say I have member functions in a class some_object as follows:

const some_type& get_some_type(...) {
   ...;
   return ...;
}

vs

const some_type get_some_type(...) {
   ...;
   return ...;
}

Is my understanding correct that assignment by calling the latter (return by value) would leave two copies of the data some_type in memory at certain points during the application's execution, while calling the former (return by reference) avoids this?

Another effort as part of the overall goal of reducing the memory footprint was to change the very definition of some_type in a manner that would preclude using the return by reference option above. In such a case, since some_type (which is actually a container of sorts, say, of data of type data_type) is used inside a loop as follows:

const some_type& = some_object->get_some_type(); // returns by ref. a large container
for(...) {
   ...;
   data_type = some_type.at(...);
   ...;
}

I assume if we are constrained to use the return by value above, then I would need to make the change as follows by introducing a new function get_some_type_at to get an element of the container by value (are there any downsides to doing this that I should be aware of, say, in performance?):

for(...) {
   ...;
   data_type = some_object->get_some_type_at(...); // returns by value a small object
   ...;
}

Again I am looking mostly for confirmation of these aspects. But details and insights are most appreciated. Thanks for your time and interest!

Was it helpful?

Solution

Most good compilers implement return value optimisation, so you needn't worry about unnecessary construction of copy objects.

Hence, choose

some_type get_some_type(...) {
   ...;
   return ...;
}

unless you're using an old compiler.

(Acknowledgement to juanchopanza; also drop the const object return; explanation in comments.)

See http://en.wikipedia.org/wiki/Return_value_optimization for more details; pointless to duplicate this here.

OTHER TIPS

Is my understanding correct that assignment by calling the latter (return by value) would leave two copies of the data some_type in memory at certain points during the application's execution, while the calling former (return by reference) avoids this?

With a modern compiler chances of that are pretty slim. The standard specifically blesses what's called return value optimization (and named return value optimization) to let a compiler avoid creating extra copies in a case like this. Every reasonably modern compiler of which I'm aware includes this optimization. In some cases (e.g., gcc) they do this optimization even when you tell the compiler not to do optimization. With optimization turned on, you'd have to look at something like 10 years (maybe more) to find a compiler that didn't do it.

C++11 adds "move" capability to do even more to ensure against the problem you're concerned with, even when you return a large object by value.

Bottom line: looks to me like what you're looking in the wrong place -- you might want to consider adding an explicit move constructor (and possibly move assignment operator) to your class, but in general, you can just return by value and be happy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top