HybridArrays.jl
HybridArrays.jl copied to clipboard
resize! of HybridArray
I use HybridArrays as a replacement for a Vector of SMatrices. Now I found the need to resize!
the Vector.
This works for Vector of SMatrices but not a HybridArray:
V = [SA[1 2; 3 4], SA[5 6; 7 8]];
resize!(V, 3) # adds one entry
H = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(randn(2,2,2));
resize!(H, 3) # errors
Is there a way to achieve this with a HybridArray?
Currently there is no such functionality but I can add it for https://github.com/JuliaArrays/ElasticArrays.jl wrapped in HybridArray
s. Would that work for you?
I didn't know ElasticArrays but it sounds interesting!
However, I understand my problem better now and solved it differently.
My first attempt to increase the Array was generate a new one and copy the data resulting in bad performance (example with short arrays):
H = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(randn(2,2,2))
H2 = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(Array{Float64}(undef, 2, 2, 4))
@btime H2[:,:,1:2] .= H #30.800 μs (333 allocations: 21.00 KiB)
But when I insted loop over the third dimension, I get good performance:
@btime for i = 1:2; H2[:,:,i] = H[:,:,i]; end #66.667 ns (2 allocations: 96 bytes)
I guess .=
is not implemented efficiently as it depends on which dimensions are Dynamic.
So from my side this issue can actually be closed.
Hm, that broadcast shouldn't be so slow but I'm not sure what causes that issue. I'll have to investigate.
I improved the benchmark a little with:
H = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(randn(2,2,2))
H2 = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(Array{Float64}(undef, 2, 2, 4))
@btime $H2[:,:,1:2] .= $H #196.189 ns (16 allocations: 512 bytes)
@btime for i = 1:2; $H2[:,:,i] = $H[:,:,i]; end #3.000 ns (0 allocations: 0 bytes)
The difference is smaller but still signifficant.
f() = begin H = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(randn(2,2,2))
H2 = HybridArray{Tuple{2,2,StaticArrays.Dynamic()}}(Array{Float64}(undef, 2, 2, 4))
H2[:,:,1:2] .= H
end
@profview for i = 1:10_000_000 f() end
tells me that most time is spend in _setindex!_scalar
, not sure if this helps.
I've spent some time investigating but I got stuck: https://discourse.julialang.org/t/tracking-the-cause-of-allocation-in-the-presence-of-a-generated-function/98215 . I have no idea why Julia failed to optimize that call and the tools I know don't help :confused: . I think it would be easier to implement resize!
for hybrid elastic arrays.
Ok, thanks for looking into this!