If Less(a, b) returns true when a is less than b, the correct way to
check if a is greater than b is to use Less(b, a). It is wrong to use
!Less(a, b) because that checks if a is greater than *or equal to* b.
1. The decreasingDistance function in Example_sortKeys makes this
mistake. Fix it.
2. The documentation of multiSorter.Less says it loops along the less
functions until it finds a comparison "that is either Less or
!Less". This is nonsense, because (Less(a, b) or !Less(a, b)) is
always true. Fix the documentation to say that it finds a
comparison "that discriminates between the two items (one is less
than the other)". The implementation already does this correctly.
Change-Id: If52b79f68e4fdb0d1095edf29bdecdf154a61b8d
Reviewed-on: https://go-review.googlesource.com/57752
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Revert "Revert "sort: improve average quicksort performance""
This reverts commit 30b87bb9aa.
See https://golang.org/cl/15688 for the CL being replayed.
Change-Id: I2ba36334003f4971f95a10536adfdd86be9a50de
Reviewed-on: https://go-review.googlesource.com/17389
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
- change way of protection from O(N^2) on duplicate values.
Previous algorithm does additional comparisons and swaps
on every split pass.
Changed algorithm does one ordinal quicksort split pass,
and if distribution is skewed, then additional pass to
separate pivot's duplicates.
Changed algorithm could be slower on very ununique slice,
but it is still protected from O(N^2).
- increase small slice size and do simple shell sort pass
to amortize worst case on small slices.
Small slice has higher probability to have skewed
distribution, so lets sort it with simpler algorithm.
benchmark old ns/op new ns/op delta
BenchmarkSortString1K 458374 388641 -15.21%
BenchmarkSortInt1K 217851 181796 -16.55%
BenchmarkSortInt64K 20539264 16730340 -18.54%
BenchmarkSort1e2 98668 95554 -3.16%
BenchmarkSort1e4 20278500 18316829 -9.67%
BenchmarkSort1e6 3215724392 2795999911 -13.05%
number of operations:
Size: Total: Swap: Less:
% % %
Sort 100 Avg -5.98% -18.43% -1.90%
Sort 100 Max -14.43% -16.02% -4.51%
Sort 300 Avg -7.50% -12.76% -5.96%
Sort 300 Max -11.29% -9.60% -4.30%
Sort 1000 Avg -12.13% -11.65% -12.25%
Sort 1000 Max -13.81% -11.77% -11.89%
Sort 3000 Avg -14.61% -9.30% -15.86%
Sort 3000 Max -15.81% -8.66% -15.19%
Sort 10000 Avg -16.10% -8.47% -17.80%
Sort 10000 Max -17.13% -7.63% -16.97%
Sort 30000 Avg -17.46% -7.56% -19.57%
Sort 30000 Max -18.24% -7.62% -17.68%
Sort 100000 Avg -18.83% -6.64% -21.33%
Sort 100000 Max -19.72% -6.70% -20.96%
Sort 300000 Avg -19.61% -6.16% -22.30%
Sort 300000 Max -20.69% -6.15% -21.81%
Sort 1000000 Avg -20.42% -5.58% -23.31%
Sort 1000000 Max -21.54% -5.56% -23.61%
Change-Id: I23868e8b52b5841b358cd5403967c9a97871e4d5
Reviewed-on: https://go-review.googlesource.com/15688
Reviewed-by: Russ Cox <rsc@golang.org>