Since we don’t actually need to the fully ordered list of specificity,
just the most specific,
I think we can maybe use the subtype operator <:
.
I think this is only correct because we want just the most specific, the others might be in another order,
since <:
only is a partial ordering. Because there are types that are neither a<:b
nor b<:a
.
But anything at the bottom must not be >:
of anything else in the list.
Which is still not enough to to give us a unique most specific.
But if we add the additional restriction that these are all answers to T
in a isa T
for some specific a
, which is true in my case, then I think now it is enough to find use a unique most specific type, modulo ambiguity.
And that is a fair bit faster
julia> using BenchmarkTools
julia> type_morespecific(a, b) = Bool(ccall(:jl_type_morespecific, Cint, (Any,Any), a, b))
type_morespecific (generic function with 1 method)
julia> is_subtype_vs(a, b) = a <: b
is_subtype_vs (generic function with 1 method)
julia> is_subtype_ts(::Type{a}, ::Type{b}) where {a,b} = a <: b
is_subtype_ts (generic function with 1 method)
julia> const types = [Tuple{Int, Int}, Tuple{Integer, Integer}, Tuple{T, T} where T<: Real, Tuple{Int, Integer}];
julia> @btime partialsort(types, 1; lt=type_morespecific)
1.304 μs (5 allocations: 304 bytes)
Tuple{Int64, Int64}
julia> @btime partialsort(types, 1; lt=is_subtype_vs)
495.861 ns (3 allocations: 208 bytes)
Tuple{Int64, Int64}
julia> @btime partialsort(types, 1; lt=is_subtype_ts)
212.740 ns (1 allocation: 112 bytes)
Tuple{Int64, Int64}
However, as I said this doesn’t overall give a correct ordering.
julia> @btime sort(types, lt=type_morespecific)
1.326 μs (6 allocations: 384 bytes)
4-element Vector{Type}:
Tuple{Int64, Int64}
Tuple{Int64, Integer}
Tuple{Integer, Integer}
Tuple{T, T} where T<:Real
julia> @btime sort(types, lt=is_subtype_vs)
515.120 ns (4 allocations: 288 bytes)
4-element Vector{Type}:
Tuple{Int64, Int64}
Tuple{Integer, Integer}
Tuple{T, T} where T<:Real
Tuple{Int64, Integer}
julia> @btime sort(types, lt=is_subtype_ts)
225.705 ns (2 allocations: 192 bytes)
4-element Vector{Type}:
Tuple{Int64, Int64}
Tuple{Integer, Integer}
Tuple{T, T} where T<:Real
Tuple{Int64, Integer}