From ef9e17718453014b680631be9e0467d91ad3d781 Mon Sep 17 00:00:00 2001 From: Stefan Pochmann Date: Fri, 31 Jan 2020 05:53:24 +0100 Subject: [PATCH 1/3] Fix power of 2. --- Objects/listsort.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/listsort.txt b/Objects/listsort.txt index 43fe1574c32393..7ff6555f8a7c79 100644 --- a/Objects/listsort.txt +++ b/Objects/listsort.txt @@ -739,7 +739,7 @@ slice (leaving off both endpoints) (2**(k-1)-1)+1 through (2**k-1)-1 inclusive = 2**(k-1) through (2**k-1)-1 inclusive, which has (2**k-1)-1 - 2**(k-1) + 1 = 2**k-1 - 2**(k-1) = - 2*2**k-1 - 2**(k-1) = + 2*2**(k-1)-1 - 2**(k-1) = (2-1)*2**(k-1) - 1 = 2**(k-1) - 1 elements. From 15146e21cb9110c679a9f4d703c148caa825de02 Mon Sep 17 00:00:00 2001 From: Stefan Pochmann Date: Fri, 31 Jan 2020 05:55:39 +0100 Subject: [PATCH 2/3] Fixed typo. --- Lib/test/sortperf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/sortperf.py b/Lib/test/sortperf.py index 171e5cef5e29fd..14a9d827ed57c5 100644 --- a/Lib/test/sortperf.py +++ b/Lib/test/sortperf.py @@ -134,7 +134,7 @@ def tabulate(r): L = list(range(half - 1, -1, -1)) L.extend(range(half)) # Force to float, so that the timings are comparable. This is - # significantly faster if we leave tham as ints. + # significantly faster if we leave them as ints. L = list(map(float, L)) doit(L) # !sort print() From 22d8ec380cb0bedcb3c8d147c0a2979b4d68b279 Mon Sep 17 00:00:00 2001 From: Stefan Pochmann Date: Sun, 2 Feb 2020 21:59:30 +0100 Subject: [PATCH 3/3] Fix misleading sentence - merge_collapse isn't always about merging the new run with preceding runs. For example [64, 32, 65] (where 65 is the new run) becomes [96, 65] by merging only the preceding runs and not merging the new run. - It's not just called to "see whether it should merge" but also to actually merge. --- Objects/listsort.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Objects/listsort.txt b/Objects/listsort.txt index 7ff6555f8a7c79..174777a2658dc6 100644 --- a/Objects/listsort.txt +++ b/Objects/listsort.txt @@ -319,13 +319,13 @@ So merging is always done on two consecutive runs at a time, and in-place, although this may require some temp memory (more on that later). When a run is identified, its base address and length are pushed on a stack -in the MergeState struct. merge_collapse() is then called to see whether it -should merge it with preceding run(s). We would like to delay merging as -long as possible in order to exploit patterns that may come up later, but we -like even more to do merging as soon as possible to exploit that the run just -found is still high in the memory hierarchy. We also can't delay merging -"too long" because it consumes memory to remember the runs that are still -unmerged, and the stack has a fixed size. +in the MergeState struct. merge_collapse() is then called to potentially +merge runs on that stack. We would like to delay merging as long as possible +in order to exploit patterns that may come up later, but we like even more to +do merging as soon as possible to exploit that the run just found is still +high in the memory hierarchy. We also can't delay merging "too long" because +it consumes memory to remember the runs that are still unmerged, and the +stack has a fixed size. What turned out to be a good compromise maintains two invariants on the stack entries, where A, B and C are the lengths of the three rightmost not-yet