cpython/Objects
Tim Peters bf121d6a69
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>
2024-03-12 19:59:42 -05:00
..
clinic gh-116621: Set manual critical section for list.extend (gh-116657) 2024-03-13 07:28:23 +09:00
mimalloc gh-115103: Delay reuse of mimalloc pages that store PyObjects (#115435) 2024-03-06 09:42:11 -05:00
stringlib gh-110964: Remove private _PyArg functions (#110966) 2023-10-17 14:30:31 +02:00
abstract.c gh-116316: Fix typo in UNARY_FUNC(PyNumber_Positive) macros (GH-116317) 2024-03-04 17:57:01 +00:00
boolobject.c gh-111999: Add signatures and improve docstrings for builtins (GH-112000) 2023-11-13 09:13:49 +02:00
bytearrayobject.c gh-115323: Add meaningful error message for using bytearray.extend with str (#115332) 2024-02-24 18:34:45 -05:00
bytes_methods.c gh-104922: remove PY_SSIZE_T_CLEAN (#106315) 2023-07-02 15:07:46 +09:00
bytesobject.c gh-108767: Replace ctype.h functions with pyctype.h functions (#108772) 2023-09-01 18:36:53 +02:00
call.c gh-106320: Remove _PyFunction_Vectorcall() API (#107071) 2023-07-22 21:44:33 +00:00
capsule.c gh-108240: Add pycore_capsule.h internal header file (#108596) 2023-08-29 01:20:02 +00:00
cellobject.c gh-110964: Remove private _PyArg functions (#110966) 2023-10-17 14:30:31 +02:00
classobject.c gh-113157 gh-89519: Fix method descriptors (gh-113233) 2023-12-21 16:08:35 -06:00
codeobject.c GH-114695: Add sys._clear_internal_caches (GH-115152) 2024-02-12 09:04:36 +00:00
complexobject.c gh-109598: make PyComplex_RealAsDouble/ImagAsDouble use __complex__ (GH-109647) 2024-01-15 16:04:17 +01:00
descrobject.c gh-101860: Expose __name__ on property (GH-101876) 2024-02-20 17:14:34 +02:00
dictnotes.txt
dictobject.c gh-112075: Enable freeing with qsbr and fallback to lock on key changed (GH-116336) 2024-03-05 09:08:18 +00:00
enumobject.c gh-106320: Create pycore_modsupport.h header file (#106355) 2023-07-03 09:39:11 +00:00
exception_handling_notes.txt GH-105848: Simplify the arrangement of CALL's stack (GH-107788) 2023-08-09 18:19:39 +00:00
exceptions.c gh-114570: Add PythonFinalizationError exception (#115352) 2024-02-14 23:35:06 +01:00
fileobject.c gh-82626: Emit a warning when bool is used as a file descriptor (GH-111275) 2024-02-05 22:51:11 +02:00
floatobject.c gh-111968: Split _Py_dictkeys_freelist out of _Py_dict_freelist (gh-115505) 2024-02-16 01:01:36 +00:00
frame_layout.md gh-109094: replace frame->prev_instr by frame->instr_ptr (#109095) 2023-10-26 13:43:10 +00:00
frameobject.c gh-113939: Frame clear, clear locals (#113940) 2024-01-31 19:14:44 +00:00
funcobject.c gh-114312: Collect stats for unlikely events (GH-114493) 2024-01-25 11:10:51 +00:00
genericaliasobject.c gh-110964: Remove private _PyArg functions (#110966) 2023-10-17 14:30:31 +02:00
genobject.c gh-111968: Split _Py_async_gen_asend_freelist out of _Py_async_gen_fr… (gh-115546) 2024-02-17 10:03:10 +09:00
interpreteridobject.c gh-101524: Only Use Public C-API in the _xxsubinterpreters Module (gh-107359) 2023-07-27 15:30:16 -06:00
iterobject.c gh-106320: Remove private _PyEval function (#108433) 2023-08-24 20:25:22 +02:00
listobject.c GH-116554: Relax list.sort()'s notion of "descending" runs (#116578) 2024-03-12 19:59:42 -05:00
listsort.txt GH-116554: Relax list.sort()'s notion of "descending" runs (#116578) 2024-03-12 19:59:42 -05:00
lnotab_notes.txt Document the co_lines method on code objects (#113682) 2024-01-03 19:29:24 +00:00
locations.md
longobject.c gh-110819: Fix ‘kind’ may be used uninitialized warning in longobject (#116599) 2024-03-12 13:50:06 +03:00
memoryobject.c gh-111178: Avoid calling functions from incompatible pointer types in memoryobject.c (GH-112863) 2023-12-11 17:43:07 +01:00
methodobject.c gh-114626: add PyCFunctionFast and PyCFunctionFastWithKeywords (GH-114627) 2024-02-15 11:05:20 +01:00
moduleobject.c gh-116437: Use new C API PyDict_Pop() to simplify the code (GH-116438) 2024-03-07 11:21:08 +02:00
namespaceobject.c gh-110964: Remove private _PyArg functions (#110966) 2023-10-17 14:30:31 +02:00
object.c gh-115491: Keep some fields valid across allocations in obmalloc (free-threading) (#115745) 2024-02-21 10:00:08 -08:00
object_layout.md gh-106293: Fix typos in Objects/object_layout.md (#106294) 2024-01-16 23:11:15 +00:00
object_layout_312.gv
object_layout_312.png
object_layout_full_312.gv
object_layout_full_312.png
obmalloc.c gh-112075: Support freeing object memory via QSBR (#116344) 2024-03-08 09:56:36 -08:00
odictobject.c gh-112075: Add critical sections for most dict APIs (#114508) 2024-02-06 14:03:43 -08:00
picklebufobject.c gh-104922: remove PY_SSIZE_T_CLEAN (#106315) 2023-07-02 15:07:46 +09:00
rangeobject.c gh-106320: Remove private _PyEval function (#108433) 2023-08-24 20:25:22 +02:00
README
setobject.c gh-112069: Make sets thread-safe with the GIL disabled (#113800) 2024-03-08 16:25:34 -05:00
sliceobject.c gh-111968: Rename freelist related struct names to Eric's suggestion (gh-115329) 2024-02-14 00:32:51 +00:00
structseq.c GH-108362: Revert "GH-108362: Incremental GC implementation (GH-108038)" (#115132) 2024-02-07 12:38:34 +00:00
tupleobject.c gh-116381: Remove bad specializations, add fail stats (GH-116464) 2024-03-08 00:21:21 +08:00
typeobject.c gh-116437: Use new C API PyDict_Pop() to simplify the code (GH-116438) 2024-03-07 11:21:08 +02:00
typeslots.inc
typeslots.py
typevarobject.c gh-110864: TypeVar constructor: Partially revert gh-110784, constraints cannot be NULL (#110922) 2023-10-16 15:01:04 +00:00
unicodectype.c
unicodeobject.c gh-112066: Use PyDict_SetDefaultRef in place of PyDict_SetDefault. (#112211) 2024-02-07 13:43:18 -05:00
unicodetype_db.h gh-96954: Fix make regen-unicodedata in out-of-tree builds (#112118) 2023-11-15 16:42:17 +00:00
unionobject.c gh-108511: Add C API functions which do not silently ignore errors (GH-109025) 2023-09-17 14:23:31 +03:00
weakrefobject.c gh-106320: Remove private _PyErr_ChainExceptions() (#108713) 2023-08-31 13:53:19 +02:00

Source files for various builtin objects