I do not understand how v3 is the code below is being allowed to mutate. What is going on there?
using StaticArrays
using BenchmarkTools
function test(v1, v2)
v3 = zeros(SVector{3,Float64})
for i in 1:10^4
v3 = (v1 .* v2) .+ v3
end
v3
end
v1 = rand(SVector{3,Float64});
v2 = rand(SVector{3,Float64});
test(v1,v2)
@btime test($v1,$v2)
And it does not allocate anything (which also surprises me, as I thought at least that v3 should have been allocated ,it is allocated in the stack and, thus, do not count? )
julia> @btime test($v1,$v2)
10.025 ÎĽs (0 allocations: 0 bytes)
3-element SArray{Tuple{3},Float64,1,3} with indices SOneTo(3):
5655.280099799662
761.1553139585608
1664.2491656557113
Yes, StaticArrays are allocated on the stack (because their size is known) and therefore don’t “count”.
v3 isn’t actually mutated. v3 = (v1 .* v2) .+ v3 creates a new vector and binds v3 to it. v3 old bind is thrown away.
Edit: to make it more clear: the array that is bound to the name v3 isn’t mutated, it’s exchanged for a whole new array, which is bound to the name v3 instead.
The fact that this is not possible (and if with a mutable vector, slower) is something that I have to get familiar with:
function test(v1, v2)
v3 = zeros(SVector{3,Float64})
for i in 1:10^4
for i in 1:3
v3[i] = (v1[i] * v2[i]) + v3[i]
end
end
v3
end
Uhm… this works (and is fast):
julia> v = [ rand(SVector{3,Float64}) for i in 1:10_000 ];
julia> function sumv!(v)
for i in 2:length(v)
v[i] = v[i] + v[i-1]
end
end
sumv! (generic function with 1 method)
julia> sumv!(v)
Now I see many other ways of using StaticArrays… I was thinking that they were much more limited.