]> Cypherpunks repositories - gostls13.git/commitdiff
sort: reduce number of comparisons needed by medianOfThree
authorMartin Möhrmann <martisch@uos.de>
Fri, 9 Jan 2015 22:25:42 +0000 (23:25 +0100)
committerRobert Griesemer <gri@golang.org>
Tue, 13 Jan 2015 19:37:02 +0000 (19:37 +0000)
For some cases we can ensure the correct order of elements in two
instead of three comparisons. It is unnecessary to compare m0 and
m1 again if m2 and m1 are not swapped.

benchmark                   old ns/op      new ns/op      delta
BenchmarkSortString1K       302721         299590         -1.03%
BenchmarkSortInt1K          124055         123215         -0.68%
BenchmarkSortInt64K         12291522       12203402       -0.72%
BenchmarkSort1e2            58027          57111          -1.58%
BenchmarkSort1e4            12426805       12341761       -0.68%
BenchmarkSort1e6            1966250030     1960557883     -0.29%

Change-Id: I2b17ff8dee310ec9ab92a6f569a95932538768a9
Reviewed-on: https://go-review.googlesource.com/2614
Reviewed-by: Robert Griesemer <gri@golang.org>
src/sort/sort.go

index 4ca027b614024a67fca894033cf29ba281cd6859..b52b54ed8f7c52e9c920f055d9d0a2adfbe23ed0 100644 (file)
@@ -75,20 +75,19 @@ func heapSort(data Interface, a, b int) {
 // Quicksort, following Bentley and McIlroy,
 // ``Engineering a Sort Function,'' SP&E November 1993.
 
-// medianOfThree moves the median of the three values data[a], data[b], data[c] into data[a].
-func medianOfThree(data Interface, a, b, c int) {
-       m0 := b
-       m1 := a
-       m2 := c
-       // bubble sort on 3 elements
+// medianOfThree moves the median of the three values data[m0], data[m1], data[m2] into data[m1].
+func medianOfThree(data Interface, m1, m0, m2 int) {
+       // sort 3 elements
        if data.Less(m1, m0) {
                data.Swap(m1, m0)
        }
+       // data[m0] <= data[m1]
        if data.Less(m2, m1) {
                data.Swap(m2, m1)
-       }
-       if data.Less(m1, m0) {
-               data.Swap(m1, m0)
+               // data[m0] <= data[m2] && data[m1] < data[m2]
+               if data.Less(m1, m0) {
+                       data.Swap(m1, m0)
+               }
        }
        // now data[m0] <= data[m1] <= data[m2]
 }