github.com/jfcg/sorty@v1.2.0/README.md (about) 1 ## sorty [](https://goreportcard.com/report/github.com/jfcg/sorty) [](https://pkg.go.dev/github.com/jfcg/sorty) 2 3 sorty is a type-specific, fast, efficient, concurrent/parallel [QuickSort](https://en.wikipedia.org/wiki/Quicksort) 4 implementation (with an improved [InsertionSort](https://en.wikipedia.org/wiki/Insertion_sort) as subroutine). 5 It is in-place and does not require extra memory (other than efficient recursive calls and goroutines). You can call 6 corresponding `Sort*()` to rapidly sort your slices (in ascending order) or collections of objects. For example: 7 ``` 8 sorty.SortS(string_slice) // native slice 9 sorty.Sort(n, lesswap) // lesswap() function based 10 ``` 11 If you have a pair of `Less()` and `Swap()`, then you can trivially write your 12 [`lesswap()`](https://pkg.go.dev/github.com/jfcg/sorty#Sort) and sort your generic 13 collections using multiple CPU cores quickly. sorty natively sorts 14 `[][]byte`,`[]float32`,`[]float64`,`[]int`,`[]int32`,`[]int64`, 15 `[]uintptr`,`[]string`,`[]uint`,`[]uint32`,`[]uint64`. 16 sorty also natively sorts `[]string` and `[][]T` (for any type `T`) 17 [by length](https://pkg.go.dev/github.com/jfcg/sorty#SortLen). 18 19 sorty is stable (as in version), well-tested and pretty careful with resources & performance: 20 - `lesswap()` operates [**faster**](https://github.com/lynxkite/lynxkite/pull/141#issuecomment-779673635) 21 than [`sort.Interface`](https://pkg.go.dev/sort#Interface) on generic collections. 22 - For each `Sort*()` call, sorty uses up to [`Mxg`](https://pkg.go.dev/github.com/jfcg/sorty#pkg-variables) 23 (3 by default, including caller) concurrent goroutines and up to one channel. 24 - Goroutines and channel are created/used **only when necessary**. 25 - `Mxg=1` (or a short input) yields single-goroutine sorting: No goroutines or channel will be created. 26 - `Mxg` can be changed live, even during an ongoing `Sort*()` call. 27 - [`Mli,Hmli,Mlr`](https://pkg.go.dev/github.com/jfcg/sorty#pkg-constants) parameters are tuned to get the best performance, see below. 28 - sorty API adheres to [semantic](https://semver.org) versioning. 29 30 ### Benchmarks 31 Comparing against [sort.Slice](https://golang.org/pkg/sort), [sortutil](https://github.com/twotwotwo/sorts), 32 [zermelo](https://github.com/shawnsmithdev/zermelo) and [radix](https://github.com/yourbasic/radix) with Go 33 version `1.17.1` on: 34 35 Machine|CPU|OS|Kernel 36 :---:|:---|:---|:--- 37 R |Ryzen 1600 |Manjaro |5.10.68 38 X |Xeon Broadwell|Ubuntu 20.04|5.11.0-1020-gcp 39 i5|Core i5 4210M |Manjaro |5.10.68 40 41 Sorting uniformly distributed random uint32 slice (in seconds): 42 43 Library(-Mxg)|R|X|i5 44 :---|---:|---:|---: 45 sort.Slice|12.18|16.78|13.98 46 sortutil| 1.48| 3.42| 3.10 47 zermelo| 2.10| 1.83| 1.12 48 sorty-1| 5.83| 7.92| 6.06 49 sorty-2| 3.07| 4.00| 3.17 50 sorty-3| 2.30| 3.29| 2.62 51 sorty-4| 1.82| 2.82| 2.27 52 sortyLsw-1|11.39|14.71|12.90 53 sortyLsw-2| 6.02| 7.49| 6.78 54 sortyLsw-3| 4.20| 5.96| 5.21 55 sortyLsw-4| 3.48| 5.18| 4.58 56 57 Sorting normally distributed random float32 slice (in seconds): 58 59 Library(-Mxg)|R|X|i5 60 :---|---:|---:|---: 61 sort.Slice|13.28|17.37|14.43 62 sortutil| 1.97| 3.95| 3.50 63 zermelo| 4.50| 4.15| 3.18 64 sorty-1| 7.21| 8.47| 6.84 65 sorty-2| 3.78| 4.31| 3.57 66 sorty-3| 2.60| 3.41| 2.78 67 sorty-4| 2.27| 3.03| 2.50 68 sortyLsw-1|12.77|15.65|13.40 69 sortyLsw-2| 6.70| 8.00| 7.05 70 sortyLsw-3| 4.60| 6.20| 5.58 71 sortyLsw-4| 3.59| 5.50| 4.78 72 73 Sorting uniformly distributed random string slice (in seconds): 74 75 Library(-Mxg)|R|X|i5 76 :---|---:|---:|---: 77 sort.Slice| 6.77| 8.96| 6.94 78 sortutil| 1.31| 2.39| 1.99 79 radix | 4.90| 4.46| 3.41 80 sorty-1| 4.80| 6.59| 5.09 81 sorty-2| 2.46| 3.31| 2.81 82 sorty-3| 1.80| 3.05| 2.63 83 sorty-4| 1.42| 2.78| 2.51 84 sortyLsw-1| 6.28| 8.53| 6.73 85 sortyLsw-2| 3.24| 4.40| 3.66 86 sortyLsw-3| 2.20| 3.74| 3.29 87 sortyLsw-4| 1.95| 3.44| 3.12 88 89 Sorting uniformly distributed random []byte slice (in seconds): 90 91 Library(-Mxg)|R|X|i5 92 :---|---:|---:|---: 93 sort.Slice| 6.87| 8.82| 7.04 94 sorty-1| 4.07| 5.31| 4.28 95 sorty-2| 2.12| 2.74| 2.38 96 sorty-3| 1.49| 2.38| 2.15 97 sorty-4| 1.30| 2.18| 1.97 98 99 Sorting uniformly distributed random string slice by length (in seconds): 100 101 Library(-Mxg)|R|X|i5 102 :---|---:|---:|---: 103 sort.Slice| 3.37| 4.08| 3.45 104 sorty-1| 1.61| 2.11| 1.67 105 sorty-2| 0.87| 1.07| 0.88 106 sorty-3| 0.61| 0.88| 0.72 107 sorty-4| 0.53| 0.80| 0.67 108 109 Sorting uniformly distributed random []byte slice by length (in seconds): 110 111 Library(-Mxg)|R|X|i5 112 :---|---:|---:|---: 113 sort.Slice| 3.55| 4.14| 3.51 114 sorty-1| 1.18| 1.39| 1.12 115 sorty-2| 0.63| 0.71| 0.60 116 sorty-3| 0.45| 0.60| 0.51 117 sorty-4| 0.39| 0.53| 0.46 118 119 ### Testing & Parameter Tuning 120 First, make sure everything is fine: 121 ``` 122 go test -timeout 1h 123 ``` 124 You can tune `Mli,Hmli,Mlr` for your platform/CPU with (optimization flags): 125 ``` 126 go test -timeout 4h -gcflags '-dwarf=0 -B -wb=0' -ldflags '-s -w' -tags tuneparam 127 ``` 128 Now update `Mli,Hmli,Mlr` in `maxc.go`, uncomment imports & respective `mfc*()` 129 calls in `tmain_test.go` and compare your tuned sorty with other libraries: 130 ``` 131 go test -timeout 1h -gcflags '-dwarf=0 -B -wb=0' -ldflags '-s -w' 132 ``` 133 Remember to build sorty (and your functions like [`SortObjAsc()`](https://pkg.go.dev/github.com/jfcg/sorty#Sort)) 134 with the same optimization flags you used for tuning. `-B` flag is especially helpful. 135 136 ### Support 137 If you use sorty and like it, please support via ETH:`0x464B840ee70bBe7962b90bD727Aac172Fa8B9C15`