Is there a performance penalty for doing the Union like this? I know that there is if I define the following
struct AArray <: AbstractArray
arr::Union{BArray, CArray}
end
it’s significantly slower, but maybe your solution is less ambiguous to the compiler?
I made a typo in my original post. Type BArray is a general type that may or may not have a type CArray inside of it so coolmap should only be defined for BArrays containing CArrays, which is different than your answer I believe.
And that is the whole point with the parametric types.
In the latter case, the type TheStruct provides basically no information on what the inner layout of an object is, because one can subtype SomeAbstractType with arbitrarily complex type. So, the compiler can only produce slow generic code with unboxing etc.
In the former case, any concrete object cannot be of type TheStruct, it will be of type TheStruct{SomeType}. If SomeType is a concrete type, then the compiler has information of the data layout from the type of object alone and can produce fast machine code.
Moreover, all types in your OP must be parametric for performance:
struct CArray{T<:Dict} <: AbstractArray
cool_mapping::T
end
struct BArray{T<:AbstractArray} <: AbstractArray
data::T
end
const AllowableATypes = Union{CArray, BArray{<:CArray}}
struct AArray{T<:AllowableATypes} <: AbstractArray
arr::T
end
Note that you can’t have BArray{CArray} in AllowableATypes, because that would disallow BArray{CArray{SomeConcreteDictType}} (cf. Array{Int} and Array{Integer}). You need a BArray parameterized by a type that is a subtype of CArray, that’s why a longer signature is required.