first, I introduce some very similar ways to represent some boring data, with reasonable benchmarks:
julia> a=SVector{3, MVector{3,Int}}([MVector{3,Int}([1,1,1]),MVector{3,Int}([1,1,1]),MVector{3,Int}([1,1,1])])
3-element SVector{3, MVector{3, Int64}} with indices SOneTo(3):
[1, 1, 1]
[1, 1, 1]
[1, 1, 1]
julia> struct mysvec
one::MVector{3,Int}
two::MVector{3,Int}
thr::MVector{3,Int}
end
julia> Base.:+(a::mysvec, b::mysvec) = a.one+b.one, a.two+b.two, a.thr+b.thr
julia> b=mysvec([1,1,1], [1,1,1], [1,1,1])
mysvec([1, 1, 1], [1, 1, 1], [1, 1, 1])
julia> c=[[1,1,1],[1,1,1],[1,1,1]]
3-element Vector{Vector{Int64}}:
[1, 1, 1]
[1, 1, 1]
[1, 1, 1]
julia> @benchmark $a+$a
BenchmarkTools.Trial: 10000 samples with 998 evaluations per sample.
Range (min β¦ max): 14.578 ns β¦ 11.243 ΞΌs β GC (min β¦ max): 0.00% β¦ 99.60%
Time (median): 29.597 ns β GC (median): 0.00%
Time (mean Β± Ο): 37.294 ns Β± 262.228 ns β GC (mean Β± Ο): 18.37% Β± 2.63%
βββ
βββββββββββββββββββββββ
ββ
β
βββββββββββββββββ
βββββββββββββββββ β
14.6 ns Histogram: frequency by time 53.1 ns <
Memory estimate: 96 bytes, allocs estimate: 3.
julia> @benchmark $b+$b
BenchmarkTools.Trial: 10000 samples with 998 evaluations per sample.
Range (min β¦ max): 18.183 ns β¦ 11.171 ΞΌs β GC (min β¦ max): 0.00% β¦ 99.42%
Time (median): 32.191 ns β GC (median): 0.00%
Time (mean Β± Ο): 40.879 ns Β± 265.808 ns β GC (mean Β± Ο): 18.01% Β± 2.81%
βββ
ββ
ββββββββ
ββ
βββββββ
βββββββββββββββ
βββββββ
β
β
β
ββββββββββββββββ β
18.2 ns Histogram: frequency by time 58.7 ns <
Memory estimate: 96 bytes, allocs estimate: 3.
julia> @benchmark $c+$c
BenchmarkTools.Trial: 10000 samples with 984 evaluations per sample.
Range (min β¦ max): 50.980 ns β¦ 13.368 ΞΌs β GC (min β¦ max): 0.00% β¦ 98.93%
Time (median): 113.817 ns β GC (median): 0.00%
Time (mean Β± Ο): 147.831 ns Β± 539.619 ns β GC (mean Β± Ο): 22.46% Β± 6.22%
ββββββ
ββββ
ββββββββββββββ
ββββ
β
β
β
ββββββββββββββββ
β
β
β
β
ββ
ββββββββββββββββββ β
51 ns Histogram: frequency by time 190 ns <
Memory estimate: 320 bytes, allocs estimate: 8.
however, if I release one condition, the static vector becomes slower than a normal vector:
julia> a=SVector{3, MVector}([MVector{3,Int}([1,1,1]),MVector{4,Int}([1,1,1,1]),MVector{3,Int}([1,1,1])])
3-element SVector{3, MVector} with indices SOneTo(3):
[1, 1, 1]
[1, 1, 1, 1]
[1, 1, 1]
julia> struct mysvec2
one::MVector{3,Int}
two::MVector{4,Int}
thr::MVector{3,Int}
end
julia> Base.:+(a::mysvec2, b::mysvec2) = a.one+b.one, a.two+b.two, a.thr+b.thr
julia> b=mysvec2([1,1,1], [1,1,1,1], [1,1,1])
mysvec([1, 1, 1], [1, 1, 1, 1], [1, 1, 1])
julia> c=[[1,1,1],[1,1,1,1],[1,1,1]]
3-element Vector{Vector{Int64}}:
[1, 1, 1]
[1, 1, 1, 1]
[1, 1, 1]
julia> @benchmark $a+$a
BenchmarkTools.Trial: 10000 samples with 200 evaluations per sample.
Range (min β¦ max): 362.120 ns β¦ 64.566 ΞΌs β GC (min β¦ max): 0.00% β¦ 98.97%
Time (median): 450.567 ns β GC (median): 0.00%
Time (mean Β± Ο): 477.896 ns Β± 882.369 ns β GC (mean Β± Ο): 2.60% Β± 1.40%
ββββββ
ββ
βββββββββββββββ
ββββββββββββββββββ
ββββββββββββββββββββββββββββ β
362 ns Histogram: frequency by time 609 ns <
Memory estimate: 192 bytes, allocs estimate: 6.
julia> @benchmark $b+$b
BenchmarkTools.Trial: 10000 samples with 998 evaluations per sample.
Range (min β¦ max): 16.423 ns β¦ 12.970 ΞΌs β GC (min β¦ max): 0.00% β¦ 99.50%
Time (median): 28.776 ns β GC (median): 0.00%
Time (mean Β± Ο): 41.415 ns Β± 315.749 ns β GC (mean Β± Ο): 21.19% Β± 2.81%
βββ
βββ
ββ
ββββ
ββββ
βββββββββββ
βββββββββββββββββββββββββββββββββββββββββ β
16.4 ns Histogram: frequency by time 68 ns <
Memory estimate: 112 bytes, allocs estimate: 3.
julia> @benchmark $c+$c
BenchmarkTools.Trial: 10000 samples with 983 evaluations per sample.
Range (min β¦ max): 57.537 ns β¦ 15.545 ΞΌs β GC (min β¦ max): 0.00% β¦ 98.95%
Time (median): 109.860 ns β GC (median): 0.00%
Time (mean Β± Ο): 147.736 ns Β± 629.855 ns β GC (mean Β± Ο): 24.53% Β± 5.75%
βββββββ
β
ββββββββ
β
β
β
ββ
βββ
β
β
ββββββββββββ
βββββββββββββββββββββββββββββββ β
57.5 ns Histogram: frequency by time 193 ns <
Memory estimate: 336 bytes, allocs estimate: 8.
I included the struct version to show that there is a theoretical gain to be made, but I would like to just treat it like a normal vector without having to define a bunch of struct operations which would almost certainly be less efficient than normal vector indexing/iterating methods. what is the correct way to make a SVector like this?