(Adaptive) Shivers sort variant of Tim sort
Hello, I developed a C sorting algorithms library that currently has a few dozens of algorithms and thousands of variants when choosing parameters (like threshold for switching to insertion sort, etc.). (I compile each variant on demand in custom tests to avoid having a bloated source file.) My benchmarks could be improved but however I found that Shivers' sort and adaptive Shivers' sort (aka Jugé's sort) performs better than Tim's sort. I don't know if it will still be true with the benchmarks in Python. If you're open to the idea that maybe Tim's sort can be improved and are willing to benchmark it, it can be done easily by switching the main natural merge strategy like I did here : https://github.com/LLyaudet/TSODLULS/commit/2968c4b4ca58ae794157dc9636ed8701... The relevant code is not very long : /** * This strategy is from ShiversSort: * see the research report by Olin Shivers, Georgia Institute of Technology, 2002. * It uses bitwise tricks to check condition on floor of logarithms in base 2 of runs lengths. * When I benchmark it, it is slightly faster than Tim's sort strategy. */ #define TSODLULS_natural_merge_main_strategy__Shivers_sort \ while(merge_state.i_run_instances_count > 1){\ size_t i_merge_at = merge_state.i_run_instances_count - 2;\ size_t i_order_of_magnitude = merge_state.arr_run_instances[i_merge_at + 1].i_length;\ if(i_order_of_magnitude < ((~i_order_of_magnitude) & merge_state.arr_run_instances[i_merge_at].i_length) ){\ break;\ }\ i_compare_result = TSODLULS_MERGE_TWO_RUNS(&merge_state, i_merge_at);\ if(i_compare_result != 0){\ goto clean_and_return_error;\ }\ }\ /** * This strategy is from AdaptiveShiversSort: * see the articles by Vincent Jugé, for example 1024 Bulletin de la SIF, avril 2020, in French, * or the preprint on arXiv or SODA 2020 proceedings. * It uses bitwise tricks to check condition on floor of logarithms in base 2 of runs lengths. * When I benchmark it, it is slightly faster than Tim's sort strategy. * Despite its ressemblance with Shivers's sort, * the distinct properties of this strategy make that JugéSort would probably be a better name than AdaptiveShiversSort, * or an even better name for the whole algorithm should be TimShiversJugéSort and I must have missed many names ;) * With AdaptiveShiversSort we avoid 'é' and diacritics in function names ;P */ #define TSODLULS_natural_merge_main_strategy__adaptive_Shivers_sort \ while(merge_state.i_run_instances_count > 2){\ size_t i_merge_at = merge_state.i_run_instances_count - 3;\ size_t i_order_of_magnitude = merge_state.arr_run_instances[i_merge_at + 1].i_length | merge_state.arr_run_instances[i_merge_at + 2].i_length;\ if(i_order_of_magnitude < ((~i_order_of_magnitude) & merge_state.arr_run_instances[i_merge_at].i_length) ){\ break;\ }\ i_compare_result = TSODLULS_MERGE_TWO_RUNS(&merge_state, i_merge_at);\ if(i_compare_result != 0){\ goto clean_and_return_error;\ }\ }\ In my library the merge strategy is a parameter and I switch its macro when compiling competitors algorithms on demand. I hope it may help. Thanks for your time. If you want to look further at my library, it works with gcc and glibc. I have not tested it on other platforms and whilst I have no compilation warning on my personal dev laptop, I do have one when I run it on the laptop I'm currently writing this email. The tests passes nevertheless. Best regards, Laurent Lyaudet
[Laurent Lyaudet <laurent.lyaudet@gmail.com>]
... My benchmarks could be improved but however I found that Shivers' sort and adaptive Shivers' sort (aka Jugé's sort) performs better than Tim's sort.
Cool! Could you move this to the issue report already open on this? Replace list sorting merge_collapse()? https://bugs.python.org/issue34561 Alas, that's been inactive for nearly 3 years, but we _were_ making some decent progress before everyone got distracted by "more important" stuff. You'll see there that Vincent Jugé contributed another version, designed to address that his sort did substantially worse than what we already have in some cases with very few runs. Which, for reasons explained there, is likely important. Before that, the best alternative known was - and by far - Munro & Wild's "powersort" merge strategy. That's deeply rooted in theory about fast approximations to optimal binary search trees. Where that left off, Vincent was going to try proving properties of his new variant, plus investigate other ideas. Alas, that's where it ended, as Vincent ran out of time too. In any case, yes, I'm entirely in favor of replacing timsort's merge strategy, by something with provably good properties even in worst cases. As explained in the issue report, the merge strategy I made up was merely the first thing I tried that didn't obviously suck ;-) - almost all the work went into making merging itself as zippy as reasonably possible..
[Laurent Lyaudet <laurent.lyaudet@gmail.com>]
... My benchmarks could be improved but however I found that Shivers' sort and adaptive Shivers' sort (aka Jugé's sort) performs better than Tim's sort.
Cool! Could you move this to the issue report already open on this?
Replace list sorting merge_collapse()? https://bugs.python.org/issue34561
Thanks for the fast and kind answer :) I just did. Sorry for not checking the bugs reports before posting. I only checked that Shivers and Jugé did not appear in the archive of the
Hello, Le sam. 28 août 2021 à 19:38, Tim Peters <tim.peters@gmail.com> a écrit : python-dev mailing list. (If it does then the search here: https://mail.python.org/archives/list/python-dev@python.org/ is broken.)
Alas, that's been inactive for nearly 3 years, but we _were_ making some decent progress before everyone got distracted by "more important" stuff.
You'll see there that Vincent Jugé contributed another version, designed to address that his sort did substantially worse than what we already have in some cases with very few runs. Which, for reasons explained there, is likely important.
Before that, the best alternative known was - and by far - Munro & Wild's "powersort" merge strategy. That's deeply rooted in theory about fast approximations to optimal binary search trees.
Where that left off, Vincent was going to try proving properties of his new variant, plus investigate other ideas. Alas, that's where it ended, as Vincent ran out of time too.
In any case, yes, I'm entirely in favor of replacing timsort's merge strategy, by something with provably good properties even in worst cases. As explained in the issue report, the merge strategy I made up was merely the first thing I tried that didn't obviously suck ;-) - almost all the work went into making merging itself as zippy as reasonably possible..
I will try to provide a patch before the end of the week. But first I will read https://www.python.org/psf/contrib/ https://devguide.python.org/ I took 5 minutes to fork and do a PR on my fork with the code for merge collapse : https://github.com/LLyaudet/cpython/pull/1 As soon as I have something more polished I'll do a PR on python repo. Any early feedback is welcome :) Best regards, Laurent
participants (2)
-
Laurent Lyaudet
-
Tim Peters