Skip to content

Commit

Permalink
avoid creating a few MethodInstances for Missing (JuliaLang#49015)
Browse files Browse the repository at this point in the history
Union-typed call edges are a little bit more expensive than other edges,
but we can easily avoid calling these functions when we know they are
not applicable, since this is one of the most common to observe.
  • Loading branch information
vtjnash authored and oscardssmith committed Mar 20, 2023
1 parent 43f90a9 commit 4b092ed
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
7 changes: 6 additions & 1 deletion base/promotion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,12 @@ function promote_typejoin(@nospecialize(a), @nospecialize(b))
c = typejoin(_promote_typesubtract(a), _promote_typesubtract(b))
return Union{a, b, c}::Type
end
_promote_typesubtract(@nospecialize(a)) = typesplit(a, Union{Nothing, Missing})
_promote_typesubtract(@nospecialize(a)) =
a === Any ? a :
a >: Union{Nothing, Missing} ? typesplit(a, Union{Nothing, Missing}) :
a >: Nothing ? typesplit(a, Nothing) :
a >: Missing ? typesplit(a, Missing) :
a

function promote_typejoin_union(::Type{T}) where T
if T === Union{}
Expand Down
11 changes: 6 additions & 5 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -578,19 +578,20 @@ elements that are not

function _sort!(v::AbstractVector, a::MissingOptimization, o::Ordering, kw)
@getkw lo hi
if nonmissingtype(eltype(v)) != eltype(v) && o isa DirectOrdering
if o isa DirectOrdering && eltype(v) >: Missing && nonmissingtype(eltype(v)) != eltype(v)
lo, hi = send_to_end!(ismissing, v, o; lo, hi)
_sort!(WithoutMissingVector(v, unsafe=true), a.next, o, (;kw..., lo, hi))
elseif eltype(v) <: Integer && o isa Perm && o.order isa DirectOrdering &&
nonmissingtype(eltype(o.data)) != eltype(o.data) &&
elseif o isa Perm && o.order isa DirectOrdering && eltype(v) <: Integer &&
eltype(o.data) >: Missing && nonmissingtype(eltype(o.data)) != eltype(o.data) &&
all(i === j for (i,j) in zip(v, eachindex(o.data)))
# TODO make this branch known at compile time
# This uses a custom function because we need to ensure stability of both sides and
# we can assume v is equal to eachindex(o.data) which allows a copying partition
# without allocations.
lo_i, hi_i = lo, hi
for (i,x) in zip(eachindex(o.data), o.data)
if ismissing(x) == (o.order == Reverse) # should i go at the beginning?
for i in eachindex(o.data) # equal to copy(v)
x = o.data[i]
if ismissing(x) == (o.order == Reverse) # should x go at the beginning/end?
v[lo_i] = i
lo_i += 1
else
Expand Down

0 comments on commit 4b092ed

Please sign in to comment.