Problem with Type of Vector of Colors/Colorants

colors::Vector{Colorant} means that each element of colors may be a different subtype of Colorant. Internally, therefore, it is an array of pointers to “boxes” (values with a type tag), a different box for each element. (Operations on such an array are consequently rather slow because the compiled code needs to look up the type of each element at runtime.) Vector{Colorant} is one specific concrete type, and no other type is allowed.

In contrast a parameter colors::AbstractVector{<:Colorant} is declaring that the argument can be any one of a set of types V{T}, for any V <: AbstractVector and T <: Colorant. A Vector{Colorant} is allowed, but so is a Vector{RGB{Float64}}, for example. For any particular type of colors that is passed, the compiler will generate a different specialized implementation (one for each type). For example, a colors::Vector{RGB{Float64}} is stored as an array of “inlined” (r,g,b) triplets (3 Float64 values in a row for each color) with no pointers or type tags for individual elements, and since the Colorant type is known at compile time the generated code can be quite efficient (as efficient as operating in C on an array of struct { double r; double g; double b; } values).

See also the discussion here, for example, and the Julia manual on Parametric Types.

2 Likes