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
README Issue #18093: Factor out the programs that embed the runtime 2014-07-25 21:52:14 +10: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 bpo-46845: Reduce dict size when all keys are Unicode (GH-31564) 2022-03-02 08:09:28 +09:00
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 GH-88116: Use a compact format to represent end line and column offsets. (GH-91666) 2022-04-21 16:10:37 +01:00
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 GH-96068: Document object layout (GH-96069) 2022-08-23 13:55:43 +01:00
object_layout_312.png GH-96068: Document object layout (GH-96069) 2022-08-23 13:55:43 +01:00
object_layout_full_312.gv GH-96068: Document object layout (GH-96069) 2022-08-23 13:55:43 +01:00
object_layout_full_312.png GH-96068: Document object layout (GH-96069) 2022-08-23 13:55:43 +01:00
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
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 bpo-41073: PyType_GetSlot() can now accept static types. (GH-21931) 2020-11-10 12:53:46 -08:00
typeslots.py bpo-41073: PyType_GetSlot() can now accept static types. (GH-21931) 2020-11-10 12:53:46 -08:00
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 bpo-46670: Remove unused macros in the Objects directory (GH-31193) 2022-02-07 16:21:41 +01:00
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

README

Source files for various builtin objects