59 lines
4.1 KiB
Text
59 lines
4.1 KiB
Text
|
go get github.com/fiatjaf/mergesortedslices
|
||
|
|
||
|
if you have any number of sorted slices you can merge them all in a single sorted slice.
|
||
|
|
||
|
this orders bigger elements first rather than the opposite -- if you want it the other way please copy-paste the code and change.
|
||
|
|
||
|
this sometimes is faster than just mashing them together like a madman and calling `slices.Sort()` then `slices.Reverse()`, but sometimes not.
|
||
|
|
||
|
goos: linux
|
||
|
goarch: amd64
|
||
|
pkg: github.com/fiatjaf/merge-sorted-slices
|
||
|
cpu: AMD Ryzen 3 3200G with Radeon Vega Graphics
|
||
|
|
||
|
BenchmarkMergeVsQuicksort/many-small/mergeall-4 10000 121018 ns/op
|
||
|
BenchmarkMergeVsQuicksort/many-small/quicksort-4 30464 38996 ns/op
|
||
|
BenchmarkMergeVsQuicksort/few-big/mergeall-4 22197 56067 ns/op
|
||
|
BenchmarkMergeVsQuicksort/few-big/quicksort-4 10000 111113 ns/op
|
||
|
BenchmarkMergeVsQuicksort/fewest-big/mergeall-4 38775 37689 ns/op
|
||
|
BenchmarkMergeVsQuicksort/fewest-big/quicksort-4 15337 91172 ns/op
|
||
|
BenchmarkMergeVsQuicksort/many-big/mergeall-4 409 2578229 ns/op
|
||
|
BenchmarkMergeVsQuicksort/many-big/quicksort-4 904 1616955 ns/op
|
||
|
BenchmarkMergeVsQuicksort/few-small/mergeall-4 797331 2328 ns/op
|
||
|
BenchmarkMergeVsQuicksort/few-small/quicksort-4 600583 2941 ns/op
|
||
|
|
||
|
for some reason using a custom comparator is significantly slower than using the hardcoded `cmp.Compare()` -- even when you actually pass in `cmp.Compare` as an argument. don't ask me why. the same performance hit (or bigger) also affects `slices.SortFunc()`.
|
||
|
|
||
|
BenchmarkMergeVsQuicksortFunc/many-small/mergeall-4 9319 151554 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/many-small/quicksort-4 14011 93110 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/few-big/mergeall-4 14103 82564 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/few-big/quicksort-4 7546 224849 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/fewest-big/mergeall-4 21457 53450 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/fewest-big/quicksort-4 9021 181349 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/many-big/mergeall-4 290 4231061 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/many-big/quicksort-4 406 2704375 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/few-small/mergeall-4 488162 3385 ns/op
|
||
|
BenchmarkMergeVsQuicksortFunc/few-small/quicksort-4 256736 6720 ns/op
|
||
|
|
||
|
this will work better on a smaller number of slices that have a bigger number of sequential values that are not interlaced, i.e.,
|
||
|
|
||
|
merging {1, 2, 4, 6, 7, 8, 13, 16, 19, 20} with {18, 22, 25, 28, 29, 30, 31} will work better than
|
||
|
merging {1, 1, 2, 3, 3, 5, 7, 8, 10, 12, 15} with {1, 2, 4, 5, 6, 9, 11, 13, 14, 16}.
|
||
|
|
||
|
now where it excels is when you need to take just the first N of the values, so you can stop the iteration at some point (which you can't do with quicksort):
|
||
|
|
||
|
BenchmarkMergeVsQuicksortLimit/many-small/mergeall-4 53628 23622 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/many-small/quicksort-4 28882 43004 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/few-big/mergeall-4 281392 5951 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/few-big/quicksort-4 9242 115081 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/fewest-big/mergeall-4 442494 4093 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/fewest-big/quicksort-4 10000 102202 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/many-big/mergeall-4 24458 51888 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/many-big/quicksort-4 639 1568560 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/few-small/mergeall-4 1286480 1074 ns/op
|
||
|
BenchmarkMergeVsQuicksortLimit/few-small/quicksort-4 377631 2668 ns/op
|
||
|
|
||
|
---
|
||
|
|
||
|
this may or may not be called a "k-way" merge algorithm.
|