I agree with @mrufsvold
that ContainerConcrete
is a good way to go. It’s worth noting that the reason your ContainerMoreConcrete
is less performant than ContainerConcrete
is that ContainerMoreConcrete
is still not concrete enough for type inference. Since the type of x
in ContainerMoreConcrete
has been declared an AbstractMatrix
, types will not always be inferable, as in this example below:
function container_multiply(c, v)
c.x*v
end
x = [1.0; 2.0;; 3.0; 4.0]
v = [5.0, 6.0]
cmc = ContainerMoreConcrete(x)
cc = ContainerConcrete(x)
Running @code_warntype
on the two containers in the function yields:
@code_warntype container_multiply(cmc, v)
MethodInstance for container_multiply(::ContainerMoreConcrete{Float64}, ::Vector{Float64})
from container_multiply(c, v) @ Main ~/Files/file.jl:21
Arguments
#self#::Core.Const(Main.container_multiply)
c::ContainerMoreConcrete{Float64}
v::Vector{Float64}
Body::Any
1 ─ %1 = Main.:*::Core.Const(*)
│ %2 = Base.getproperty(c, :x)::AbstractMatrix{Float64}
│ %3 = (%1)(%2, v)::Any
└── return %3
and
@code_warntype container_multiply(cc, v)
MethodInstance for container_multiply(::ContainerConcrete{Matrix{Float64}}, ::Vector{Float64})
from container_multiply(c, v) @ Main ~/Files/file.jl:21
Arguments
#self#::Core.Const(Main.container_multiply)
c::ContainerConcrete{Matrix{Float64}}
v::Vector{Float64}
Body::Vector{Float64}
1 ─ %1 = Main.:*::Core.Const(*)
│ %2 = Base.getproperty(c, :x)::Matrix{Float64}
│ %3 = (%1)(%2, v)::Vector{Float64}
└── return %3