Static array or tuple allocate at construction

I have some code that allocates on the heap (and shouldn’t) while constructing a StaticArray. The hunt leads me to this MWE:

using StaticArrays,  BenchmarkTools
@btime SVector{4,Float64}(2. *i for i=1:4)     # good, no allocation
@btime ntuple(i->2. *i,4)                      # good too, no allocation

v = SVector{4,Float64}(1.,2.,3.,4.)
@btime SVector{4,Float64}(v[i] for i=1:4)      # but why does this allocate? 
@btime ntuple(i->v[i],4)                       # and this too?

Why does accessing an array element allocate? To check that this is not a measurement artifact, I package the allocating code in a on-liner function and @btime 'd it.

Of course the above MVE is nonsensical - I could just copy v. Nonsensical or not, I do not understand what causes the allocation, and understanding this would probably help me correct my real code.

NB: I’m still on Julia 1.9, for no good reason… Is that an issue here?

:slightly_smiling_face:

See the performance tips page in the manual: Performance Tips · The Julia Language

In particular, you’re accessing a global untyped variable (v), and there are possibly also issues with the way you capture it in the closure. Both issues are covered on that page. Also possibly check the BenchmarkTools.jl Readme and docs, they also cover these issues.

3 Likes

Good grief, I fell for this one again :stuck_out_tongue:. Indeed, just declaring const

const v = SVector{4,Float64}(1.,2.,3.,4.)

eliminates all allocations in the above MVE.

Which also means my MVE did not capture the actual problem of my original code. I’ll be back.

1 Like