Skip to content

Commit

Permalink
Add SubArray optimization to sorting (#52072)
Browse files Browse the repository at this point in the history
  • Loading branch information
LilithHafner committed Nov 22, 2023
1 parent 05f4b05 commit abfc2c6
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
46 changes: 38 additions & 8 deletions base/sort.jl
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,34 @@ internal or recursive calls.
"""
function _sort! end

# TODO: delete this optimization when views have no overhead.
const UnwrappableSubArray = SubArray{T, 1, <:AbstractArray{T}, <:Tuple{AbstractUnitRange, Vararg{Number}}, true} where T
"""
SubArrayOptimization(next) <: Algorithm
Unwrap certain known SubArrays because views have a performance overhead 😢
Specifically, unwraps some instances of the type
$UnwrappableSubArray
"""
struct SubArrayOptimization{T <: Algorithm} <: Algorithm
next::T
end

_sort!(v::AbstractVector, a::SubArrayOptimization, o::Ordering, kw) = _sort!(v, a.next, o, kw)
function _sort!(v::UnwrappableSubArray, a::SubArrayOptimization, o::Ordering, kw)
@getkw lo hi
# @assert v.stride1 == 1
parent = v.parent
if parent isa Array && !(parent isa Vector) && hi - lo < 100
# vec(::Array{T, ≠1}) allocates and is therefore somewhat expensive.
# We don't want that for small inputs.
_sort!(v, a.next, o, kw)
else
_sort!(vec(parent), a.next, o, (;kw..., lo = lo + v.offset1, hi = hi + v.offset1))
end
end

"""
MissingOptimization(next) <: Algorithm
Expand Down Expand Up @@ -1223,14 +1251,16 @@ future versions of Julia.
If `next` is stable, then `InitialOptimizations(next)` is also stable.
The specific optimizations attempted by `InitialOptimizations` are
[`MissingOptimization`](@ref), [`BoolOptimization`](@ref), dispatch to
[`InsertionSort`](@ref) for inputs with `length <= 10`, and [`IEEEFloatOptimization`](@ref).
"""
InitialOptimizations(next) = MissingOptimization(
BoolOptimization(
Small{10}(
IEEEFloatOptimization(
next))))
[`SubArrayOptimization`](@ref), [`MissingOptimization`](@ref), [`BoolOptimization`](@ref),
dispatch to [`InsertionSort`](@ref) for inputs with `length <= 10`, and
[`IEEEFloatOptimization`](@ref).
"""
InitialOptimizations(next) = SubArrayOptimization(
MissingOptimization(
BoolOptimization(
Small{10}(
IEEEFloatOptimization(
next)))))
"""
DEFAULT_STABLE
Expand Down
6 changes: 3 additions & 3 deletions test/sorting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -791,9 +791,9 @@ end
let
requires_uint_mappable = Union{Base.Sort.RadixSort, Base.Sort.ConsiderRadixSort,
Base.Sort.CountingSort, Base.Sort.ConsiderCountingSort,
typeof(Base.Sort.DEFAULT_STABLE.next.next.big.next.yes),
typeof(Base.Sort.DEFAULT_STABLE.next.next.big.next.yes.big),
typeof(Base.Sort.DEFAULT_STABLE.next.next.big.next.yes.big.next)}
typeof(Base.Sort.DEFAULT_STABLE.next.next.next.big.next.yes),
typeof(Base.Sort.DEFAULT_STABLE.next.next.next.big.next.yes.big),
typeof(Base.Sort.DEFAULT_STABLE.next.next.next.big.next.yes.big.next)}

function test_alg(kw, alg, float=true)
for order in [Base.Forward, Base.Reverse, Base.By(x -> x^2)]
Expand Down

0 comments on commit abfc2c6

Please sign in to comment.