]> git.ipfire.org Git - thirdparty/Python/cpython.git/commit
GH-116554: Relax list.sort()'s notion of "descending" runs (#116578)
authorTim Peters <tim.peters@gmail.com>
Wed, 13 Mar 2024 00:59:42 +0000 (19:59 -0500)
committerGitHub <noreply@github.com>
Wed, 13 Mar 2024 00:59:42 +0000 (19:59 -0500)
commitbf121d6a694bea4fe9864a19879fe0c70c4e0656
tree24954c37d350938872453294dbed2755eddf1e4b
parent7d1abe9502641a3602e9773aebc29ee56d8f40ae
GH-116554: Relax list.sort()'s notion of "descending" runs (#116578)

* GH-116554: Relax list.sort()'s notion of "descending" run

Rewrote `count_run()` so that sub-runs of equal elements no longer end a descending run. Both ascending and descending runs can have arbitrarily many sub-runs of arbitrarily many equal elements now. This is tricky, because we only use ``<`` comparisons, so checking for equality doesn't come "for free". Surprisingly, it turned out there's a very cheap (one comparison) way to determine whether an ascending run consisted of all-equal elements. That sealed the deal.

In addition, after a descending run is reversed in-place, we now go on to see whether it can be extended by an ascending run that just happens to be adjacent. This succeeds in finding at least one additional element to append about half the time, and so appears to more than repay its cost (the savings come from getting to skip a binary search, when a short run is artificially forced to length MIINRUN later, for each new element `count_run()` can add to the initial run).

While these have been in the back of my mind for years, a question on StackOverflow pushed it to action:

https://stackoverflow.com/questions/78108792/

They were wondering why it took about 4x longer to sort a list like:

[999_999, 999_999, ..., 2, 2, 1, 1, 0, 0]

than "similar" lists. Of course that runs very much faster after this patch.

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
Lib/test/test_sort.py
Misc/NEWS.d/next/Core and Builtins/2024-03-11-00-45-39.gh-issue-116554.gYumG5.rst [new file with mode: 0644]
Objects/listobject.c
Objects/listsort.txt