# Return value optimization and named return value optimization

**URL:** <https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782>\
**Category:** General Usage\
**Created:** [September 25, 2022, 3:25pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782 "2022-09-25T15:25:51Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [September 25, 2022, 3:25pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782/1 "2022-09-25T15:25:51Z")

</div>

Does Julia have these optimizations available like in C++? I.e., if I preallocate a value in the caller to store the return from the callee, will the callee write to that memory, or will it be allocated and then copied? From what I understand these optimizations are not possible in Julia.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [September 25, 2022, 4:57pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782/2 "2022-09-25T16:57:22Z")

</div>

Julia uses pass by sharing as opposed to pass by value, so passing and returning values doesn’t create copies in the first place.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [September 25, 2022, 5:02pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782/3 "2022-09-25T17:02:02Z")

</div>

I think in theory Julia will allocate more memory than C++ in this case, not less.

However:

> **[Compiler Explorer - C++](https://godbolt.org/z/6EGPnzG6f)**
>
> void baz(std::vector& x);
> 
> static std::vector foo(size\_t N){
> return std::vector(N);
> }
> void bar(size\_t N){
> std::vector x;
> for (size\_t i = 0; i \< 100; ++i){
> x = foo(N);
> baz(x);
> }
> }

seems C++ still allocates before each memset in the loop here.

The call to `memset` is dominated by `operator new`.

Perhaps there is a better test?

With a stack allocated & size known at compile time array, C++ does well, but Julia would do well here too (other than it taking more work to manage lifetimes/pass it to non-inlined functions):

> **[Compiler Explorer - C++](https://godbolt.org/z/vEaGhaMWY)**
>
> constexpr size\_t N = 1600;
> 
> void baz(std::array& x);
> 
> static std::array foo(){
> std::array x;
> x.fill(3.5);
> return x;
> }
> void bar(){
> std::array x;
> for (size\_t i = 0; i \< 100; ++i){
> x = foo();
> baz(x);
> }
> }

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [September 25, 2022, 5:50pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782/4 "2022-09-25T17:50:12Z")

</div>

If I’m understanding your question correctly, you can do the same thing in Julia:

```julia
callee!(x::Ref{Int}) = x[] = 1
function caller()
    x = Ref{Int}()
    callee!(x)
    println(x[])
end

```

But you shouldn’t do this generally. Julia is quite good about not allocating at all for the return value, effectively allowing values to move into registers and making it _faster_ than pre-allocating storage for the return value:

```julia
julia> using BenchmarkTools

julia> @noinline callee!(x::Ref{Int}) = x[] = 1
callee! (generic function with 1 method)

julia> @noinline fastcallee(::Any) = 1
fastcallee (generic function with 1 method)

julia> x = Ref{Int}();

julia> @btime callee!($x)
  3.141 ns (0 allocations: 0 bytes)
1

julia> @btime fastcallee($x)
  1.264 ns (0 allocations: 0 bytes)
1

```

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [September 25, 2022, 6:04pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782/5 "2022-09-25T18:04:07Z")

</div>

But I would think preallocation would be faster for larger arrays. I can see how it holds for scalars. Thanks for the response. In particular, for the use case where you will call the function many times.

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [September 25, 2022, 6:58pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782/6 "2022-09-25T18:58:14Z")

</div>

Yes, for arrays you often want to pre-allocate the storage. Julia’s abundant functions ending in `!` (“warning: mutates one or more of the inputs”) are a hint that this is well-supported. And for small arrays (e.g., 2x2), you may find that even there it’s better to return a StaticArray (from the StaticArrays.jl package).

---

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [September 25, 2022, 8:19pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782/7 "2022-09-25T20:19:05Z")

</div>

We don’t want to preallocate StaticArrays because they are stack allocated, I presume. So there would be no speed up to do so. Is this correct?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 25, 2022, 8:27pm UTC](https://discourse.julialang.org/t/return-value-optimization-and-named-return-value-optimization/87782/8 "2022-09-25T20:27:00Z")

</div>

Right, you should only consider pre-allocation for heap-allocated values.
