cpython/Lib
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
..
__phello__
asyncio gh-113538: Revert "gh-113538: Add asycio.Server.{close,abort}_clients (#114432)" (#116632) 2024-03-12 00:31:49 +00:00
collections gh-116485: Fixed the typo (#116486) 2024-03-08 08:04:50 +00:00
concurrent Simplify concurrent.futures.process code by using itertools.batched() (GH-114221) 2024-01-27 10:29:38 +02:00
ctypes gh-71052: Change Android's sys.platform from "linux" to "android" 2024-03-11 19:25:39 +00:00
curses gh-60436: fix curses textbox backspace/del (#103783) 2023-04-26 22:54:07 +02:00
dbm gh-100414: Make dbm.sqlite3 the preferred dbm backend (#115447) 2024-02-14 13:47:19 +00:00
email gh-76511: Fix email.Message.as_string() for non-ASCII message with ASCII charset (GH-116125) 2024-03-05 17:49:01 +02:00
encodings gh-102388: Add windows_31j to aliases for cp932 codec (#102389) 2024-02-19 17:01:35 +09:00
ensurepip gh-114965: Updated bundled pip to 24.0 (gh-114966) 2024-02-03 17:45:09 +00:00
html gh-100210: Correct the comment link for unescaping HTML (#100212) 2023-02-19 11:18:12 +01:00
http gh-100985: Consistently wrap IPv6 IP address during CONNECT (GH-100986) 2024-02-17 10:10:12 +00:00
idlelib gh-88516: show file proxy icon in IDLE editor windows on macOS (#112894) 2024-02-23 02:15:39 +00:00
importlib gh-116381: Specialize CONTAINS_OP (GH-116385) 2024-03-07 03:30:11 +08:00
json doc: Use super() in subclassed JSONEncoder examples (GH-115565) 2024-02-28 14:54:12 +01:00
logging Replace stat.ST_xxx usage with os.stat().st_xxx (#116501) 2024-03-08 18:49:09 +01:00
multiprocessing gh-71052: Change Android's sys.platform from "linux" to "android" 2024-03-11 19:25:39 +00:00
pathlib pathlib ABCs: follow all symlinks in PathBase.glob() (#116293) 2024-03-04 02:26:33 +00:00
pydoc_data Python 3.13.0a5 2024-03-12 21:11:08 +01:00
re GH-83162: Rename re.error for better clarity. (#101677) 2023-12-11 15:45:08 -05:00
site-packages
sqlite3 gh-91602: Add iterdump() support for filtering database objects (#114501) 2024-02-06 12:34:56 +01:00
sysconfig gh-103708: Make directory layout in sysconfig implementation configurable (#103709) 2023-12-29 17:55:17 +00:00
test GH-116554: Relax list.sort()'s notion of "descending" runs (#116578) 2024-03-12 19:59:42 -05:00
tkinter gh-97928: Partially restore the behavior of tkinter.Text.count() by default (GH-115031) 2024-02-11 12:43:14 +02:00
tomllib
turtledemo gh-111092: Make turtledemo run without default root enabled (#111093) 2023-10-19 23:58:41 -04:00
unittest gh-75988: Fix issues with autospec ignoring wrapped object (#115223) 2024-03-08 19:14:32 +00:00
urllib gh-74668: Fix support of bytes in urllib.parse.parse_qsl() (GH-115771) 2024-03-05 17:49:50 +02:00
venv Update venv activate.bat to escape custom PROMPT variables on Windows (GH-114885) 2024-02-02 18:59:53 +00:00
wsgiref gh-111768: Add wsgiref.util.is_hop_by_hop to __all__ (#111770) 2023-11-08 15:29:47 +00:00
xml gh-115398: Expose Expat >=2.6.0 reparse deferral API (CVE-2023-52425) (GH-115623) 2024-02-29 14:52:50 -08:00
xmlrpc xmlrpc.client uses datetime.datetime.isoformat() (#105741) 2023-06-14 17:00:40 +02:00
zipfile gh-67837, gh-112998: Fix dirs creation in concurrent extraction (GH-115082) 2024-02-11 12:38:07 +02:00
zoneinfo gh-106233: Fix stacklevel in zoneinfo.InvalidTZPathWarning (GH-106234) 2024-02-06 15:08:56 +02:00
__future__.py
__hello__.py
_aix_support.py
_collections_abc.py gh-91896: Deprecate collections.abc.ByteString (#102096) 2023-05-04 09:39:33 -07:00
_compat_pickle.py gh-75552: Remove deprecated tkinter.tix module (GH-104902) 2023-05-27 12:34:19 -05:00
_compression.py
_markupbase.py
_opcode_metadata.py gh-116381: Remove bad specializations, add fail stats (GH-116464) 2024-03-08 00:21:21 +08:00
_osx_support.py gh-102362: Fix macOS version number in result of sysconfig.get_platform() (GH-112942) 2023-12-18 18:51:58 -05:00
_py_abc.py
_pydatetime.py gh-49766: Make date-datetime comparison more symmetric and flexible (GH-114760) 2024-02-11 13:06:43 +02:00
_pydecimal.py
_pyio.py gh-95782: Fix io.BufferedReader.tell() etc. being able to return offsets < 0 (GH-99709) 2024-02-17 11:16:06 +00:00
_pylong.py gh-102515: Remove unused imports in the Lib/ directory (#102516) 2023-03-08 11:45:38 +00:00
_sitebuiltins.py
_strptime.py bpo-36959: Fix error messages for invalid ISO format string in _strptime() (GH-13408) 2023-12-26 19:26:17 +00:00
_threading_local.py
_weakrefset.py
abc.py gh-87864: Use correct function definition syntax in the docs (#103312) 2023-04-11 16:50:25 +03:00
antigravity.py
argparse.py gh-116159: argparse: performance improvement parsing large number of options (#116162) 2024-03-01 11:52:53 +01:00
ast.py gh-112364: Correct unparsing of backslashes and quotes in ast.unparse (#115696) 2024-02-21 10:24:08 +00:00
base64.py bpo-31116: Add Z85 variant to base64 (GH-30598) 2024-02-25 19:17:54 +02:00
bdb.py gh-80675: Set f_trace_lines = True on all frames upon pdb.set_trace() (#110881) 2023-11-04 19:59:36 +00:00
bisect.py GH-102833: Mention the key function in the docstrings (GH-103009) 2023-03-25 02:19:20 -05:00
bz2.py
calendar.py gh-112240: Add option to calendar module CLI to specify the weekday to start each week (GH-112241) 2024-01-29 16:58:21 +00:00
cmd.py gh-52161: Enhance Cmd support for docstrings (#110987) 2024-01-03 19:37:34 +00:00
code.py GH-102895 Add an option local_exit in code.interact to block exit() from terminating the whole process (GH-102896) 2023-10-18 11:36:43 -07:00
codecs.py gh-66143: Allow copying and pickling of CodecInfo object (GH-109235) 2023-09-29 20:07:09 +03:00
codeop.py gh-113744: Add a new IncompleteInputError exception to improve incomplete input detection in the codeop module (#113745) 2024-01-30 16:21:30 +00:00
colorsys.py gh-106498: Revert incorrect colorsys.rgb_to_hls change (#106627) 2023-07-11 11:07:20 -04:00
compileall.py gh-105931: Fix surprising compileall stripdir behaviour (GH-108671) 2023-10-23 13:55:39 +00:00
configparser.py gh-107625: configparser: Raise error if a missing value is continued (GH-107651) 2024-03-06 14:05:54 +00:00
contextlib.py gh-103791: handle BaseExceptionGroup in contextlib.suppress() (#111910) 2023-11-10 13:32:36 +00:00
contextvars.py
copy.py gh-109868: Skip deepcopy memo check for empty memo (GH-109869) 2023-09-29 10:28:01 +03:00
copyreg.py
cProfile.py gh-69990: Make Profile.print_stats support sorting by multiple values (GH-104590) 2024-02-16 12:03:46 +00:00
csv.py gh-114628: Display csv.Error without context (#115005) 2024-02-04 20:57:54 -05:00
dataclasses.py gh-109653: Just import recursive_repr in dataclasses (gh-109822) 2024-03-05 13:12:00 -05:00
datetime.py gh-84976: Add back UTC to datetime.__all__ (#104920) 2023-05-25 11:18:56 -04:00
decimal.py
difflib.py
dis.py gh-112720: make it easier to subclass and modify dis.ArgResolver's jump arg resolution (#115564) 2024-02-16 19:25:19 +00:00
doctest.py gh-115341: Fix loading unit tests with doctests in -OO mode (GH-115342) 2024-02-19 19:03:21 +02:00
enum.py gh-116600: [Enum] fix global Flag repr (GH-116615) 2024-03-11 15:41:53 -07:00
filecmp.py gh-57141: Add dircmp shallow option (GH-109499) 2024-03-04 17:27:43 +00:00
fileinput.py Use bool in fileinput.input() docstring and tests for the inplace argument (GH-111998) 2024-01-27 23:47:55 +02:00
fnmatch.py GH-72904: Add glob.translate() function (#106703) 2023-11-13 17:15:56 +00:00
fractions.py gh-102840: Fix confused traceback when floordiv or mod operations happens between Fraction and complex objects (GH-102842) 2024-02-10 16:37:19 +02:00
ftplib.py gh-114241: Fix and improve the ftplib CLI (GH-114242) 2024-01-21 22:16:45 +02:00
functools.py gh-72249: Include the module name in the repr of partial object (GH-101910) 2024-02-25 22:55:19 +02:00
genericpath.py gh-101196: Make isdir/isfile/exists faster on Windows (GH-101324) 2023-02-08 14:34:24 +00:00
getopt.py
getpass.py gh-76912: Raise OSError from any failure in getpass.getuser() (#29739) 2023-11-27 10:05:55 -08:00
gettext.py gh-88434: Emit deprecation warnings for non-integer numbers in gettext if translation not found (GH-110574) 2023-10-14 09:07:02 +03:00
glob.py gh-79382: Fix recursive glob() with trailing "**" (GH-115134) 2024-02-11 12:24:13 +02:00
graphlib.py
gzip.py gh-112529: Implement GC for free-threaded builds (#114262) 2024-01-25 10:27:36 -08:00
hashlib.py gh-99108: Refactor _sha256 & _sha512 into _sha2. (#101924) 2023-02-15 22:08:20 -08:00
heapq.py
hmac.py gh-112999: Replace the outdated "deprecated" directives with "versionchanged" (GH-113000) 2023-12-12 18:31:04 +02:00
imaplib.py
inspect.py gh-101293: Fix support of custom callables and types in inspect.Signature.from_callable() (GH-115530) 2024-03-01 13:32:16 +02:00
io.py gh-111356: io: Add missing documented objects to io.__all__ (#111370) 2023-11-10 16:18:52 +09:00
ipaddress.py gh-109466: Add ipv6_mapped property to IPv4Address (#109467) 2023-11-05 16:50:31 +00:00
keyword.py gh-103763: Implement PEP 695 (#103764) 2023-05-15 20:36:23 -07:00
linecache.py gh-86291: linecache: get module name from __spec__ if available (GH-22908) 2024-02-20 16:47:41 +00:00
locale.py gh-111187: Postpone removal version for locale.getdefaultlocale() to 3.15 (#111188) 2023-10-25 16:47:41 +03:00
lzma.py
mailbox.py #gh-75705: Set unixfrom envelope in mailbox._mboxMMDF (GH-107117) 2024-02-06 20:44:12 +02:00
mimetypes.py gh-111741: Recognise image/webp as a standard format in the mimetypes module (GH-111742) 2024-01-31 17:33:46 +02:00
modulefinder.py
netrc.py
ntpath.py gh-88569: add ntpath.isreserved() (#95486) 2024-01-26 18:14:24 +00:00
nturl2path.py
numbers.py
opcode.py gh-116381: Specialize CONTAINS_OP (GH-116385) 2024-03-07 03:30:11 +08:00
operator.py
optparse.py
os.py gh-113191: Add support of os.fchmod() on Windows (GH-113192) 2023-12-24 10:57:11 +00:00
pdb.py gh-90095: Make .pdbrc work properly and add some reasonable tests (#110496) 2024-03-11 21:27:00 +00:00
pickle.py gh-85567: Fix resouce warnings in pickle and pickletools CLIs (GH-113618) 2024-01-06 00:12:34 +02:00
pickletools.py gh-115146: Fix typo in pickletools.py documentation (GH-115148) 2024-02-08 10:12:58 +02:00
pkgutil.py gh-97850: Deprecate find_loader and get_loader in pkgutil (GH-98520) 2023-05-03 16:11:54 -07:00
platform.py gh-116493: Remove old Python 2.x _winreg imports from platform.py (GH-116494) 2024-03-08 12:42:21 +00:00
plistlib.py gh-111803: Support loading more deeply nested lists in binary plist format (GH-114024) 2024-01-13 15:26:55 +02:00
poplib.py gh-106200: Remove unused imports (#106201) 2023-06-28 11:55:41 +00:00
posixpath.py gh-114709: Fix exceptions raised by posixpath.commonpath (#114710) 2024-02-18 00:24:58 -08:00
pprint.py [pprint]: Add docstring about PrettyPrinter.underscore_numbers parameter (#112963) 2023-12-13 12:04:17 +00:00
profile.py gh-69990: Make Profile.print_stats support sorting by multiple values (GH-104590) 2024-02-16 12:03:46 +00:00
pstats.py GH-83162: Rename re.error for better clarity. (#101677) 2023-12-11 15:45:08 -05:00
pty.py gh-96522: Fix deadlock in pty.spawn (#96639) 2023-05-19 13:22:43 +00:00
py_compile.py
pyclbr.py
pydoc.py gh-116143: Fix race condition in pydoc _start_server (#116144) 2024-03-06 07:39:51 -07:00
queue.py gh-96471: Correct docs for queue shutdown (#115838) 2024-02-25 16:53:21 +00:00
quopri.py
random.py gh-111881: Import _sha2 lazily in random (#111889) 2023-11-09 23:10:21 +01:00
reprlib.py gh-109818: reprlib.recursive_repr copies __type_params__ (#109819) 2023-09-27 19:26:42 -07:00
rlcompleter.py
runpy.py gh-99437: runpy: decode path-like objects before setting globals 2024-01-15 16:58:50 +00:00
sched.py
secrets.py
selectors.py gh-110038: KqueueSelector must count all read/write events (#110039) 2023-09-28 17:25:10 +00:00
shelve.py gh-107089: Improve Shelf.clear method performance (gh-107090) 2023-07-29 09:08:11 +09:00
shlex.py
shutil.py gh-71052: Change Android's sys.platform from "linux" to "android" 2024-03-11 19:25:39 +00:00
signal.py gh-112559: Avoid unnecessary conversion attempts to enum_klass in signal.py (#113040) 2023-12-23 17:07:52 -08:00
site.py gh-84995: Run sys.__interactivehook__() on asyncio REPL startup (#20517) 2024-03-01 11:39:16 -08:00
smtplib.py gh-65495: Use lowercase mail from and rcpt to in smtplib.SMTP (#107019) 2023-07-22 16:46:59 +02:00
socket.py gh-114077: Fix OverflowError in socket.sendfile() when pass count >2GiB (GH-114079) 2024-01-16 11:31:34 +00:00
socketserver.py gh-103673: Add missing ForkingUnixStreamServer and ForkingUnixDatagramServer socketservers (#103674) 2023-04-24 22:35:52 +00:00
sre_compile.py
sre_constants.py
sre_parse.py
ssl.py gh-107361: strengthen default SSL context flags (#112389) 2024-03-06 13:44:58 -08:00
stat.py gh-113666: Adding missing UF_ and SF_ flags to module 'stat' (#113667) 2024-01-15 12:22:43 +01:00
statistics.py gh-115532: Add kernel density estimation to the statistics module (gh-115863) 2024-02-25 17:46:47 -06:00
string.py
stringprep.py
struct.py
subprocess.py gh-116167: Allow disabling the GIL with PYTHON_GIL=0 or -X gil=0 (#116338) 2024-03-11 11:02:58 -04:00
symtable.py gh-85098: Implement functional CLI of symtable (#109112) 2023-11-07 16:32:16 +00:00
tabnanny.py gh-102856: Python tokenizer implementation for PEP 701 (#104323) 2023-05-21 01:03:02 +01:00
tarfile.py gh-115256: Remove refcycles from tarfile writing (GH-115257) 2024-03-04 13:26:32 +00:00
tempfile.py gh-59616: Support os.chmod(follow_symlinks=True) and os.lchmod() on Windows (GH-113049) 2023-12-14 13:28:37 +02:00
textwrap.py gh-107369: optimize textwrap.indent() (#107374) 2023-07-29 06:37:23 +00:00
this.py
threading.py gh-114271: Make _thread.ThreadHandle thread-safe in free-threaded builds (GH-115190) 2024-03-01 13:43:12 -08:00
timeit.py gh-105052:update timeit function's description (#105060) 2023-08-27 03:22:27 -04:00
token.py gh-107015: Remove async_hacks from the tokenizer (#107018) 2023-07-26 16:34:15 +01:00
tokenize.py gh-115154: Fix untokenize handling of unicode named literals (#115171) 2024-02-19 14:54:10 +00:00
trace.py gh-38807: Fix race condition in Lib/trace.py (GH-110143) 2024-01-17 22:02:14 +02:00
traceback.py gh-113358: Fix rendering tracebacks with exceptions with a broken __getattr__ (GH-113359) 2024-01-16 09:49:24 +00:00
tracemalloc.py
tty.py gh-114328: tty cbreak mode should not alter ICRNL (#114335) 2024-01-21 15:25:52 -08:00
turtle.py no-issue: Capitalise 'PhotoImage' (gh-108958) 2023-09-25 21:37:40 +09:00
types.py gh-109599: Add types.CapsuleType (#109600) 2023-09-25 19:50:39 +02:00
typing.py gh-116127: PEP-705: Add ReadOnly support for TypedDict (#116350) 2024-03-12 07:49:39 -07:00
uuid.py gh-71052: Change Android's sys.platform from "linux" to "android" 2024-03-11 19:25:39 +00:00
warnings.py gh-113781: Silence AttributeError in warning module during Python finalization (GH-113813) 2024-01-09 21:44:05 +02:00
wave.py gh-105096: Deprecate wave getmarkers() method (#105098) 2023-05-31 12:09:41 +00:00
weakref.py
webbrowser.py gh-85644: webbrowser: Use $XDG_CURRENT_DESKTOP to check desktop (GH-21731) 2024-03-02 12:48:24 +00:00
zipapp.py gh-104527: zippapp will now avoid appending an archive to itself. (gh-106076) 2023-06-26 10:09:08 +01:00
zipimport.py Fix typos in variable names, function names, and comments (GH-101868) 2023-12-01 09:37:40 +00:00