well-goknown/vendor/fiatjaf.com/lib/merge-sorted-slices
2025-01-10 23:12:51 -05:00
..
helpers.go replace lightningpub with alby 2025-01-10 23:12:51 -05:00
merge.go replace lightningpub with alby 2025-01-10 23:12:51 -05:00
mergefunc.go replace lightningpub with alby 2025-01-10 23:12:51 -05:00
README replace lightningpub with alby 2025-01-10 23:12:51 -05:00

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.