Skip to content

Commit

Permalink
Change to Hoare partitioning for list.sort
Browse files Browse the repository at this point in the history
wren-lang#1141 identified two problems with the existing implementation, namely that it was very slow when presented with lists which were either already sorted or all the same.

The purpose of this PR is to solve those problems by changing from Lomuto to Hoare partitioning. As shown by the figures in the above issue, this should not lead to performance degradation for small 'random' lists and may even be a little quicker for large lists.

This change would be invisible to users as only private methods are affected and does not require any changes to the documentation or tests.
  • Loading branch information
PureFox48 authored Mar 3, 2023
1 parent 2430d7d commit 6a2a96d
Showing 1 changed file with 15 additions and 13 deletions.
28 changes: 15 additions & 13 deletions src/vm/wren_core.wren
Original file line number Diff line number Diff line change
Expand Up @@ -334,28 +334,30 @@ class List is Sequence {
}

quicksort_(low, high, comparer) {
if (low < high) {
if (low >= 0 && high >= 0 && low < high) {
var p = partition_(low, high, comparer)
quicksort_(low, p - 1, comparer)
quicksort_(p + 1, high, comparer)
quicksort_(low, p, comparer)
quicksort_(p+1, high, comparer)
}
}

partition_(low, high, comparer) {
var p = this[high]
var mid = ((low + high)/2).floor
var p = this[mid]
var i = low - 1
for (j in low..(high-1)) {
if (comparer.call(this[j], p)) {
var j = high + 1
while (true) {
while (true) {
i = i + 1
var t = this[i]
this[i] = this[j]
this[j] = t
if (!comparer.call(this[i], p)) break
}
while (true) {
j = j - 1
if (!comparer.call(p, this[j])) break
}
if (i >= j) return j
swap(i, j)
}
var t = this[i+1]
this[i+1] = this[high]
this[high] = t
return i+1
}

toString { "[%(join(", "))]" }
Expand Down

0 comments on commit 6a2a96d

Please sign in to comment.