Back when we couldn’t rely on optimizing compilers with their fancy copy elision, move semantics and all sorts of other goodness, we had to pass “out” references or pointers to hold return value instead of using return. But surely it’s no longer useful with modern C++? Plenty of talks and articles claim that to be the case and since returning values is more readable and avoids doesn’t suffer from aliasing issues, that’s what I use by default.
At the same time, every time I hear some big claims, Carl Sagan’s "Extraordinary claims require extraordinary evidence" come to mind. So I’ve tried a bunch of benchmarks and they indeed didn’t show much difference in terms of performance. But just like tests do not prove correctness, a bunch of benchmarks is certainly not a proof. So how about a counter-example?
Easy
According to quick-bench updating a reference is 1.4 times faster than returning by value
Again, this doesn’t mean that returning values is less performant - it simply means that context matters and if such scenario ends up on a hot path, it may be worthwhile to consider legacy C++.
This “legacy” technique is often used in case where it’s possible to reuse allocated memory. For example, when using 2 queues for BFS, instead of creating a new queue for the next layer, it’s better to swap previous and next layer queues, so that their backing memory is reused. Btw, BFS can be easily implemented with just a single queue, but that’s a different topic.
That’s why when designing performance friendly APIs, you may consider providing a low-level API that takes a destination value by reference, so that clients have more options to control memory usage,
and a user-friendly API that returns it by value
for cases when it either doesn’t make a difference in terms of perf, or when convenience takes precedence.
I feel like it's a bit of an artificial scenario. We would normally do:
```
DataHolder dataHolder = copy(src);
```
which should be as fast as (if not faster than):
```
DataHolder dataHolder;
copy(dataHolder, src);
```