How to avoid containers of abstract parametric types?

You can try to leverage union splitting. Define a union type of all possible trades and use this to declare your vector.
Here is an example:

using BenchmarkTools

N=100
struct A{T}
    a::T
end

function myfill!(X)
    for i=1:length(X)
        if i%3==0
            X[i]=A(Int16(i))
        elseif i%3==1
            X[i]=A(Int32(i))
        elseif i%3==2
            X[i]=A(Int64(i))
        end
    end
end

function mysum(X)
    s::Int64=0
    for x in X
        s+=x.a
    end
    s
end

VA=Vector{A}(undef,N)
myfill!(VA)
@show mysum(VA)
@btime mysum(VA)

const U=Union{A{Int16}, A{Int32}, A{Int64}}
VU=Vector{U}(undef,N)
myfill!(VU)
@show mysum(VU)
@btime mysum(VU)

It gives

mysum(VA) = 5050
3.109 μs (138 allocations: 2.16 KiB)
mysum(VU) = 5050
106.416 ns (1 allocation: 16 bytes)

I wrote about union splitting here.

4 Likes