I’m curious if there is a way to have a small, local array without allocations.
Here is a short, contrived example:
julia> function foo(x)
arr = [1.0, 2.0, 3.0]
if x < 1
arr[1] *= x
elseif x < 2
arr[2] *= x
elseif x < 3
arr[3] *= x
end
return sum(arr)
end
foo (generic function with 1 method)
julia> @time foo(1.9)
0.000006 seconds (1 allocation: 48 bytes)
7.8
I’m assuming the allocations are due to arr.
StaticArrays doesn’t seems to be a solution since they are immutable and MVectors are heap-allocated.
Perhaps you could give Bumper.jl a go? I’ve not really used it myself, but it seems like it might do the trick:
using Bumper
using BenchmarkTools
function foo(x)
@no_escape begin
arr = @alloc(typeof(x), 3)
arr .= 1:3
if x < 1
arr[1] *= x
elseif x < 2
arr[2] *= x
elseif x < 3
arr[3] *= x
end
sum(arr)
end
end
## --
foo(2.0) # 9.0
@btime foo(2.0) # 16.994 ns (0 allocations: 0 bytes)
Did you try it? If it does not escape it may be stack allocated by the compiler. (use @btime or you may get an apparent allocation from the output to the REPL).
Thanks for the suggestion! I hadn’t tried it and just assumed it would be heap allocated. Looks like you’re right and the compiler turned it into a stack allocation.
julia> function foo2(x)
arr = MVector(1.0, 2.0, 3.0)
if x < 1
arr[1] *= x
elseif x < 2
arr[2] *= x
elseif x < 3
arr[3] *= x
end
return sum(arr)
end
foo2 (generic function with 1 method)
julia> @btime foo2(1.9)
3.333 ns (0 allocations: 0 bytes)
7.8