Will return allocate memory?

Hi guys, looking at the following two versions of codes. I found more allocations in version 2 perhaps because b is returned in version 2. However, b = [a] is also operated in both versions. Why is there a big difference in allocation?

BTW, b is stored in heap or stack and why? it seems b[1] === a so b[1] is a reference., but b is mutable structure and should be stored in the heap I guess.

Version 1

using BenchmarkTools
using StaticArrays
function m2()
    a = SVector(1:32...)
    b = [a]
    a === b[1]
end
@btime m2() # 0 allocations
  2.200 ns (0 allocations: 0 bytes)
true

Version 2

using BenchmarkTools
using StaticArrays
function m2()
    a = SVector(1:32...)
    b = [a]
    #a === b[1]
end
@btime m2() # 0 allocations
34.511 ns (1 allocation: 336 bytes)
1-element Vector{SVector{32, Int64}}:
 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10  …  23, 24, 25, 26, 27, 28, 29, 30, 31, 32]

Return doesn’t allocate, but it can prevent an allocation from being removed. Consider the following pair of examples

f1(n) = rand(n)
f2(n) = (rand(n); return nothing)

f1 obviously has to allocate a length n vector since that is what the function returns. f2 can be optimized to a simple return nothing because although, the function as written creates the same vector as f1, it provably doesn’t let anyone observe that the vector was created.

1 Like

so you mean Julia compiler has done something in stage of compiling to prevent computing when running?

That is correct. If Julia can conclude it does not need to compute, it will not.

julia> f(n) = n + 3
f (generic function with 1 method)

julia> g(n) = (n + 3; nothing)
g (generic function with 1 method)

julia> @code_llvm f(5)
;  @ REPL[1]:1 within `f`
define i64 @julia_f_136(i64 signext %0) #0 {
top:
; ┌ @ int.jl:87 within `+`
   %1 = add i64 %0, 3
; └
  ret i64 %1
}

julia> @code_llvm g(5)
;  @ REPL[2]:1 within `g`
define void @julia_g_147(i64 signext %0) #0 {
top:
  ret void
}

rand is a bad example though. rand does have an effect. It will change the next call to rand.

4 Likes