Removing nested abstract containers

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
1 Like