Special casing small integers known at compile time

I see this sort of code sometimes and it makes me cringe

similar(a::Array{T,1}) where {T}                    = Vector{T}(undef, size(a,1))
similar(a::Array{T,2}) where {T}                    = Matrix{T}(undef, size(a,1), size(a,2))
similar(a::Array{T,1}, S::Type) where {T}           = Vector{S}(undef, size(a,1))
similar(a::Array{T,2}, S::Type) where {T}           = Matrix{S}(undef, size(a,1), size(a,2))

Because we already have this

similar(a::AbstractArray{T}) where {T}                             = similar(a, T)
similar(a::AbstractArray, ::Type{T}) where {T}                     = similar(a, T, to_shape(axes(a)))
similar(a::AbstractArray{T}, dims::Tuple) where {T}                = similar(a, T, to_shape(dims))
similar(a::AbstractArray{T}, dims::DimOrInd...) where {T}          = similar(a, T, to_shape(dims))
similar(a::AbstractArray, ::Type{T}, dims::DimOrInd...) where {T}  = similar(a, T, to_shape(dims))

I believe that in this case it is written to special case low low numbers of arguments to avoid packing and unpacking into an NTuple, but I’m not sure. Is this necessary for maximum performance? Is it possible to delegate those special casings to the compiler whenever the NTuple's N is known at compile time (almost always)? Does the compiler already do this?

I believe this is one where due to bootstrap order, we don’t have those methods yet. in other words, I don’t think this is necessary outside Base.

1 Like

Thanks! So then Arrays.jl is bootstrapped and similar is needed before AbstractArrays.jl is bootstrapped. What is the bootstrap order?

The bootstrap order looks to be in this file:

Thanks! And indeed array.jl is imported before abstractarray.jl