5 ms·
Blitsort is an in-place stable adaptive rotate merge sort
- scandum 5y agoMight be worth noting that it's faster than quicksort, std::stable_sort, and timsort.
- jtc331 5y agoOn certain data sets.
- CJefferson 5y agoI wonder why they don't compare against std::sort? That seems like most people's standard choice.
- mlochbaum 5y agoThese are all pretty slow on 32-bit integers, which you're using for testing. Could you please include a comparison with pdqsort, or at least mention that pdqsort is to be preferred when an element fits in a register (as it certainly will be if you're only beating timsort by 20% or so)? It's frustrating to see sorting algorithms with some effort spent on benchmarking and still have to guess at whether it's practical based on how much slower the comparison points are than the state of the art. Radix sorts (like your own wolfsort!) will also be much faster on the benchmarks presented, although that's sort of misleading since they are very good at uniformly random input and not so good at other distributions.
- scandum 5y agopdqsort isn't stable and still suffers from killer inputs. Not sure how well this will paste: Name | Items | Type | Best | Average | Loops | Samples | Distribution -------- | -------- | ---- | -------- | -------- | --------- | ------- | ---------------- blitsort | 100000 | 32 | 0.005962 | 0.006532 | 1 | 100 | random order pdqsort | 100000 | 32 | 0.002665 | 0.002802 | 1 | 100 | random order | | | | | | | blitsort | 100000 | 32 | 0.000069 | 0.000078 | 1 | 100 | ascending order pdqsort | 100000 | 32 | 0.000098 | 0.000100 | 1 | 100 | ascending order | | | | | | | blitsort | 100000 | 32 | 0.001138 | 0.001196 | 1 | 100 | ascending saw pdqsort | 100000 | 32 | 0.003245 | 0.003317 | 1 | 100 | ascending saw | | | | | | | blitsort | 100000 | 32 | 0.003777 | 0.003843 | 1 | 100 | generic order pdqsort | 100000 | 32 | 0.000819 | 0.000851 | 1 | 100 | generic order | | | | | | | blitsort | 100000 | 32 | 0.000051 | 0.000060 | 1 | 100 | descending order pdqsort | 100000 | 32 | 0.000202 | 0.000207 | 1 | 100 | descending order | | | | | | | blitsort | 100000 | 32 | 0.000815 | 0.000845 | 1 | 100 | descending saw pdqsort | 100000 | 32 | 0.002307 | 0.002368 | 1 | 100 | descending saw | | | | | | | blitsort | 100000 | 32 | 0.001761 | 0.001774 | 1 | 100 | random tail pdqsort | 100000 | 32 | 0.002560 | 0.002572 | 1 | 100 | random tail | | | | | | | blitsort | 100000 | 32 | 0.003328 | 0.003374 | 1 | 100 | random half pdqsort | 100000 | 32 | 0.002651 | 0.002854 | 1 | 100 | random half | | | | | | | blitsort | 100000 | 32 | 0.000593 | 0.000938 | 1 | 100 | ascending tiles pdqsort | 100000 | 32 | 0.002316 | 0.002482 | 1 | 100 | ascending tiles
- nightcracker 5y agoWhat do you mean by "suffers from killer inputs"? It is always O(n log n) by falling back to heapsort, so I don't think any input can be described as a "killer".
- mlochbaum 5y agoYou should explain these issues in the repository, not in Hacker News comments! A benchmark of 100,000 32 bit integers suggests that you will be comparing against algorithms that do well on that benchmark when it's not the case at all. The concept of stability doesn't apply when elements that compare the same are indistinguishable, which is the case for integers. And I think it's an exaggeration to say pdqsort has "killer inputs". In your benchmarks the patterned data always sorts faster than random, so the most you can say is that merge sort exploits some kinds of structure better (I have seen patterns where it does worse, but not by much). I expect timsort has some similar advantages over blitsort because of its ability to find natural runs while blitsort always starts at size 32—try an up-down pattern with runs of length 50 for instance. The absolute worse case for pdqsort is a fallback to heapsort. With pivot randomization it's pretty much impossible on large arrays unless they are engineered to make pdqsort fail, and you end up sorting the array three times slower or something. Not much of a DOS attack. Having a fast merge sort is definitely useful in a lot of situations (my thoughts at [1]), and I've been interested in quadsort particularly for that purpose (blitsort seems to emphasize lower external memory usage which I've never had a use for). Half as fast as pdqsort on random data is actually somewhat better than I expected. It feels dishonest to see "Blitsort has exceptional performance" followed by selective benchmarks showing worse algorithms, and it makes it much harder to figure out what blitsort is good for. [1] https://mlochbaum.github.io/BQN/implementation/primitive/sort.html#on-quicksort-versus-merge-sort https://mlochbaum.github.io/BQN/implementation/primitive/sor...
- scandum 5y agoWell, blitsort's performance is exceptional in the sense that it's 15% faster than the next fastest stable in-place sort. As for stability, it's useful when you need to sort a table with an integer index. So it might be of value to database software. I probably should point out some of the weakness on the README. Agreed on pdqsort being 3x slower worst case on "killer" input, but it's my understanding that's why it's not being used to replace std::sort. As for runs of 50, haven't benched those, though I assume gridsort (https://github.com/scandum/gridsort https://github.com/scandum/gridsort) would handle those rather well.
- mosaic_school 5y agoLove this! Functions look clean and fas Also great README (documentation, evaluation, ..) I did not see a license file though. Is the repository intended as public domain? UPDATE: thanks, apparently I'm trained to skip file head sections.
- kzrdude 5y agoIt's using a qsort-like interface using a function pointer for the comparison - surely a C++ like implementation has a lot to gain here?
- scandum 5y agoCorrect, if you uncomment //#define cmp(a,b) (*(a) > *(b)) in blitsort.h it'll run about 25% faster. Probably still slower than a native C++ implementation since it'll evaluate to (a > b) > 0 rather than (a > b), not sure if the compiler will optimize that.
- lpapez 5y agoBlitsort supports long doubles and 8, 16, 32, and 64 bit data types. By using 32 or 64 bit pointers it's possible to sort any other data type. Seems quite limited, wonder how it compares to radix sort.
- acmj 5y agoIn the source code, it is not apparent where the size restriction comes from. It seems to me that it can be easily modified to work with any data types. Maybe I am wrong. I am more concerned with this sentence: > Blitsort's performance is similar to that of quadsort as long as the auxiliary memory is greater or equal to the square root of the array being sorted, which comes out at 262,144 elements with the default stack of 512 elements. Performance on larger arrays degrades marginally. I wonder what "marginally" means here. What if we sort 10 million integers?
- nuclearnice3 5y agoIs the included bench.c the right way to answer that question? 1m random dist size 128 avg qsort 0.206549 blitsort 0.281630 10m random dist size 32 avg qsort 2.963479 blitsort 4.394143 100m random dist size 128 avg qsort 34.996847 blitsort 54.102616
- scandum 5y agoIt is, those numbers are less favorable than they are on my own machine. The speed of your RAM memory is likely to have an influence on performance. My system is running at 2133MHz.
- deleted 5y ago[deleted]
- nuclearnice3 5y agoInteresting. 16 GB 2133 MHz LPDDR3 Built with Apple clang version 12.0.5 (clang-1205.0.22.11) gcc -O3 bench.c
- beeforpork 5y agoWhat is the license for this code?
- hypertele-Xii 5y agoCopyright (C) 2014-2021 Igor van den Hoven ivdhoven@gmail.com Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- StefanKarpinski 5y agoI.e. MIT license
- amelius 5y agoAs a layman I'd expect advanced sorting algorithms to depend on the dimensions of the underlying memory architecture, e.g. size of CPU caches, and memory latency, bandwidth and such.