The floors

A merge that decides per run whether to gallop

Merging two sorted lists of repeated values, a merge that gallops along every equal run beats the textbook merge while the runs average more than about thirty keys a list and loses below, a rule about the whole input. A merge that learns the runs as it goes was predicted to match the better of the two on uniform values and beat both on skewed ones. The proposal's rule — gallop when the last few runs averaged long — cannot learn a run that has not ended: at one, two or four values it walks every key. Timsort's own rule, applied to equal answers — walk until a bar of consecutive equal answers, then gallop, the bar moving by one as galloping pays or fails — does what was predicted. On uniform values it stays within a hundredth of a comparison a key of the better merge; under Zipf 1, at 4,096 keys a list and 1,024 values, it makes 0.447 comparisons a key against 0.595 walking and 0.594 galloping, a quarter under both.

The runs a short list cannot have measured two ways to merge sorted lists whose keys take few values. The three-way textbook merge compares the heads of the two lists, and when they are equal takes a key from each — two keys placed for one comparison. The run merge, on an equal answer, gallops along each list to find where that value’s run ends, comparing the run’s first key with the keys one, three, seven places on until one differs, then halving back, and places both runs whole before comparing across again. Galloping pays on long runs and costs on short ones. At every list length measured it stopped paying at the same place, when a value’s run averages between sixteen and thirty-two keys a list, because a gallop over a run of rr keys costs about 4log⁡2r+14 \log_2 r + 1 comparisons where walking it costs rr halves of one.

That is a rule about the whole input, a threshold on its mean run, and that page’s closing section noticed that a skewed input would want it value by value: gallop over the run of a common value, walk the run of a rare one. A merge cannot know a run’s length before it explores it, but it can know how the last few runs went, the way Timsort’s merge raises and lowers its bar for galloping — the merge most programs call when they sort, as the sort the library ships found. The proposal predicted that a merge galloping only when its last few runs averaged long would match the better of the two merges within a few per cent on uniform values, on both sides of their crossing, and beat both on skewed values. It named the failure: on a skewed input long and short runs alternate in no order, and a bar set by the last few runs is set by the wrong ones.

Four merges, and lists with a law in them

The lists are drawn so that the proposal’s worry can happen. Each list has mm keys, from 256 to 4,096, drawn from kk values, from one to twice mm. Under a Zipf law of exponent ss the value of rank rr is drawn with probability in proportion to 1/(r+1)s1/(r+1)^s; the ranks are assigned to the values in a random order, so that along the sorted lists common and rare values interleave and a long run is as likely to follow a short one as another long one. Exponent nought is uniform. Thirty-two pairs of lists are merged at every setting, and every comparison is counted, across or inside a list.

Four merges are compared. Walk is the three-way textbook merge. Gallop is the earlier page’s run merge, galloping over every equal run. The history rule is the proposal’s: on an equal answer, gallop if the mean length of the last four runs the merge has learned exceeds a threshold θ, from 4 to 64 keys, and walk otherwise; a gallop learns its runs’ lengths exactly, and a walk learns a run’s length as the number of consecutive equal answers it gives, once the run ends. The bar is Timsort’s rule moved from wins to equal answers: on equal answers the merge walks, counting them, and when the count of consecutive equal answers for one value reaches a bar it gallops to the end of the run; after a gallop that extended the run by at least the bar, the bar falls by one, and otherwise it rises by one. The bar starts at seven, Timsort’s own starting value.

On skewed values the bar beats both

On keys drawn under Zipf 1, Timsort's bar beats both merges once the values are many: at 1,024 values it makes 0.447 comparisons a key against 0.595 walking and 0.594 galloping, 25% under the better — galloping the common values' long runs and walking the rare ones'Comparisons a key of the output merging two sorted lists of 4,096 keys drawn from k values under a Zipf law of exponent 1, common and rare values interleaved, thirty-two pairs a point. Walk every run: 1 0.500, 2 0.500, 4 0.503, 8 0.508, 16 0.513, 32 0.519, 64 0.528, 128 0.538, 256 0.552, 512 0.571, 1,024 0.595, 2,048 0.622, 4,096 0.650, 8,192 0.677. Gallop every run: 1 0.006, 2 0.011, 4 0.020, 8 0.036, 16 0.064, 32 0.109, 64 0.181, 128 0.285, 256 0.406, 512 0.514, 1,024 0.594, 2,048 0.653, 4,096 0.694, 8,192 0.729. Gallop by the last four runs: 1 0.500, 2 0.500, 4 0.503, 8 0.265, 16 0.190, 32 0.180, 64 0.238, 128 0.448, 256 0.536, 512 0.564, 1,024 0.597, 2,048 0.625, 4,096 0.651, 8,192 0.679. Timsort's bar: 1 0.006, 2 0.012, 4 0.022, 8 0.038, 16 0.066, 32 0.111, 64 0.184, 128 0.289, 256 0.365, 512 0.400, 1,024 0.447, 2,048 0.492, 4,096 0.533, 8,192 0.572.00.2000.4000.6000.800values the keys are drawn fromcomparisons a key of the output12481632641282565121K2K4K8Kgallop every rungallop by the last four runswalk every runTimsort's bar4,096 keys a listZipf 1
Fig. 1 Comparisons a key of the output, against the number of values, at 4,096 keys a list under Zipf 1: walk, gallop, the history rule at θ = 16, and the bar. At 1,024 values: 0.595, 0.594, 0.597 and 0.447. At 256: 0.552, 0.406, 0.536 and 0.365. At four values: 0.503, 0.020, 0.503 and 0.022.

Under Zipf 1, at 4,096 keys a list and 1,024 values, the bar makes 0.447 comparisons a key against 0.595 for walking and 0.594 for galloping: a quarter under both. This is the proposal’s prediction for skewed values, and it holds wherever the values are many. Where they are few, every run is long and galloping everything is right; the bar pays a little for walking the first few equal answers of every run before it gallops, 0.022 against galloping’s 0.020 at four values.

The mechanism is the one the proposal hoped for. Under a Zipf law the most common value holds a large share of each list — at exponent 1 and 1,024 values about an eighth — so its run is hundreds of keys long, the next few values’ runs hundreds too, and the next hundred values’ runs tens. The long tail of rare values has runs of one or two. Walking pays the long runs a comparison for every two keys; galloping pays the short runs four or five comparisons to discover they hold one key. The bar walks every run’s first seven or so equal answers, which a rare value never reaches, and gallops the rest, which only the common values have.

On uniform values it stays near the better

On uniform values Timsort's bar stays near the better of the two merges on both sides of their crossing — never more than 0.012 comparisons a key over, at 256 values — while the rule that gallops by the last four runs walks every run when the values are fewComparisons a key of the output merging two sorted lists of 4,096 keys drawn from k values uniformly, thirty-two pairs a point. Walk every run: 1 0.500, 2 0.500, 4 0.503, 8 0.509, 16 0.515, 32 0.524, 64 0.534, 128 0.549, 256 0.569, 512 0.599, 1,024 0.640, 2,048 0.691, 4,096 0.761, 8,192 0.837. Gallop every run: 1 0.006, 2 0.010, 4 0.020, 8 0.037, 16 0.068, 32 0.120, 64 0.209, 128 0.355, 256 0.582, 512 0.887, 1,024 1.168, 2,048 1.279, 4,096 1.241, 8,192 1.165. Gallop by the last four runs: 1 0.500, 2 0.500, 4 0.503, 8 0.274, 16 0.180, 32 0.171, 64 0.230, 128 0.362, 256 0.570, 512 0.599, 1,024 0.640, 2,048 0.691, 4,096 0.761, 8,192 0.837. Timsort's bar: 1 0.006, 2 0.012, 4 0.022, 8 0.040, 16 0.070, 32 0.122, 64 0.211, 128 0.357, 256 0.581, 512 0.601, 1,024 0.640, 2,048 0.691, 4,096 0.761, 8,192 0.837.00.5001values the keys are drawn fromcomparisons a key of the output12481632641282565121K2K4K8Kgallop every runwalk every rungallop by the last four runsTimsort's bar4,096 keys a listuniform values
Fig. 2 The same four merges on uniform values at 4,096 keys a list. Walk and gallop cross between 128 and 256 values. The bar is within 0.012 comparisons a key of the better merge at every number of values; the history rule walks every run up to four values.

On uniform values the bar stays within about a hundredth of a comparison a key of the better merge on both sides of their crossing, never more than 0.012 over, at the crossing itself. The proposal’s other prediction holds too, in its strong form: “within a few per cent” was the target, and the bar is within about two per cent of the better merge from 32 values up. Below that, where both merges cost a few hundredths of a comparison a key, a few thousandths is a larger share, and the bar is up to a fifth over galloping in ratio while being under three thousandths of a comparison over it in count.

At the crossing, uniform values make runs that all have about the same expected length: at 256 values and 4,096 keys a list, sixteen keys, with the spread chance gives them. The bar gallops a run once the run has passed its current bar and learns from each gallop, so it settles at a bar where galloping and walking cost about the same, which is exactly where the crossing is. It cannot beat the better merge there, because there is nothing to separate — every value is equally common — and it does not lose much to it.

The history rule cannot learn a run that has not ended

A merge that gallops by the last runs it learned cannot learn a run that has not ended: at 1 to 4 values, where every run is long, it walks them all, 0.500 comparisons a key against the bar's 0.022; where the runs are short it does no better than walking, and the bar beats it at every number of values from 64Comparisons a key of the output at 1,024 keys a list under Zipf 1, for the merge that gallops when the mean of the last four runs it learned exceeds 4, 16 or 64 keys, and for Timsort's bar. Last four runs over 4: 1 0.500, 2 0.500, 4 0.506, 8 0.315, 16 0.263, 32 0.342, 64 0.477, 128 0.591, 256 0.632, 512 0.659, 1,024 0.700, 2,048 0.715. Last four runs over 16: 1 0.500, 2 0.500, 4 0.506, 8 0.315, 16 0.267, 32 0.445, 64 0.556, 128 0.582, 256 0.610, 512 0.637, 1,024 0.672, 2,048 0.699. Last four runs over 64: 1 0.500, 2 0.500, 4 0.506, 8 0.371, 16 0.479, 32 0.533, 64 0.556, 128 0.578, 256 0.603, 512 0.635, 1,024 0.665, 2,048 0.694. Timsort's bar: 1 0.022, 2 0.041, 4 0.072, 8 0.122, 16 0.200, 32 0.324, 64 0.414, 128 0.463, 256 0.515, 512 0.557, 1,024 0.600, 2,048 0.638.00.2000.4000.6000.800values the keys are drawn fromcomparisons a key of the output12481632641282565121K2Klast four runs over 4last four runs over 16last four runs over 64Timsort's bar1,024 keys a listZipf 1
Fig. 3 At 1,024 keys a list under Zipf 1, the history rule at θ = 4, 16 and 64 against the bar. At one, two and four values every history rule walks every key, 0.500 comparisons a key against the bar’s 0.022 to 0.072. From 64 values up the bar is under every history rule.

The proposal’s own rule fails where its premise fails: at one, two or four values the history rule walks every run, 0.500 comparisons a key against the bar’s 0.022 at one value, because a walk learns a run’s length only when the run ends, and on a list of one value no run ever ends. It needs four runs learned before it will gallop at all, and with four values each list has only four runs. Where the values are many it learns, and it does no better than walking: at every number of values from 64, the bar beats every history rule.

The failure the proposal named — long and short runs alternating, the last few runs being the wrong ones — is real, and it is the smaller of the history rule’s two problems. The larger is that a run’s length is the one thing a walk cannot tell until the run is over, and by then the decision whether to gallop it has been made. The bar decides inside the run: it walks while the run is short enough that walking costs less than galloping would, and gallops the moment the run has shown itself long. It reads the current run, not the last ones, and needs no history of other runs at all except to set the bar, which moves by one at a time.

Where the gain is

Under a skewed law the bar gains where the values are many, most under Zipf 1: at 4,096 keys a list and 1,024 values it makes 1.001, 0.999, 0.752 and 0.893 times the better merge's comparisons under Zipf 0, 0.5, 1 and 1.5; where the values are few it pays a little for walking the first steps of every runThe bar's comparisons a key divided by the better of walking and galloping, against the number of values, at 4,096 keys a list, for Zipf exponents 0, 0.5, 1, 1.5. Zipf 0: 1 1.128, 2 1.134, 4 1.106, 8 1.064, 16 1.034, 32 1.018, 64 1.010, 128 1.006, 256 1.021, 512 1.004, 1,024 1.001, 2,048 1.000, 4,096 1.000, 8,192 1.000. Zipf 0.5: 1 1.128, 2 1.124, 4 1.106, 8 1.069, 16 1.038, 32 1.021, 64 1.011, 128 1.006, 256 0.987, 512 0.988, 1,024 0.999, 2,048 1.003, 4,096 1.004, 8,192 1.003. Zipf 1: 1 1.128, 2 1.123, 4 1.111, 8 1.070, 16 1.039, 32 1.021, 64 1.015, 128 1.016, 256 0.897, 512 0.778, 1,024 0.752, 2,048 0.791, 4,096 0.820, 8,192 0.845. Zipf 1.5: 1 1.128, 2 1.125, 4 1.115, 8 1.073, 16 1.040, 32 1.034, 64 1.000, 128 0.924, 256 0.897, 512 0.894, 1,024 0.893, 2,048 0.897, 4,096 0.897, 8,192 0.901.0.8001values the keys are drawn fromthe bar's comparisons over the better merge's12481632641282565121K2K4K8KZipf 0.5Zipf 0Zipf 1.5Zipf 11 = the better of walking and galloping4,096 keys a list
Fig. 4 The bar’s comparisons over the better merge’s, against the number of values, at 4,096 keys a list, under Zipf 0, 0.5, 1 and 1.5. At 1,024 values: 1.001, 0.999, 0.752 and 0.893.

Under a skewed law the bar gains where the values are many, most under Zipf 1: at 4,096 keys a list and 1,024 values it makes 1.001, 0.999, 0.752 and 0.893 times the better merge’s comparisons under exponents 0, 0.5, 1 and 1.5. Zipf 0.5 is too flat to separate common runs from rare ones; at 1,024 values its commonest value’s run is a few dozen keys and a typical run a handful, so galloping and walking each lose on the other’s runs about equally and the bar gains nothing. Zipf 1.5 is so steep that a few values hold most of each list and galloping everything is already close to right, so there is less for the bar to add. Zipf 1 sits where both kinds of run are common, and there the bar gains a quarter.

Under Zipf 1 the bar's advantage grows with the lists: its best is 0.922, 0.800, 0.752 times the better merge at 256, 1,024, 4,096 keys a list, because longer lists give the common values longer runs to gallop and the rare ones no longer runs to walkThe bar's comparisons a key over the better of walking and galloping, against the number of values, under Zipf 1, at 256, 1,024, 4,096 keys a list. 256 keys: 1 1.194, 2 1.178, 4 1.159, 8 1.122, 16 0.981, 32 0.922, 64 0.962, 128 0.984, 256 0.996, 512 1.006. 1,024 keys: 1 1.154, 2 1.149, 4 1.135, 8 1.086, 16 1.045, 32 1.054, 64 0.920, 128 0.800, 256 0.854, 512 0.878, 1,024 0.901, 2,048 0.919. 4,096 keys: 1 1.128, 2 1.123, 4 1.111, 8 1.070, 16 1.039, 32 1.021, 64 1.015, 128 1.016, 256 0.897, 512 0.778, 1,024 0.752, 2,048 0.791, 4,096 0.820, 8,192 0.845.0.80011.20values the keys are drawn fromthe bar's comparisons over the better merge's12481632641282565121K2K4K8K256 keys a list1,024 keys a list4,096 keys a list1 = the better of walking and gallopingZipf 1
Fig. 5 Under Zipf 1, the bar’s comparisons over the better merge’s at 256, 1,024 and 4,096 keys a list. Its best is 0.922, 0.800 and 0.752 times the better merge.

The bar’s advantage grows with the lists: its best is 0.922, 0.800 and 0.752 times the better merge at 256, 1,024 and 4,096 keys a list. Longer lists give the common values longer runs, which galloping covers in logarithmically many comparisons, and give the rare values no longer runs, which walking covers in one or two. The two kinds of run grow apart as the lists grow, which is when a merge that treats them differently earns most.

What the bar gallops

The bar gallops where galloping pays and stops where it does not: on uniform values it gallops 86% of the equal runs it meets at 128 values and 0% at 1,024; under Zipf 1 it keeps galloping 6% of them at 1,024 values — the common values' runs, long however many rare values there areOf the equal runs the bar's merge meets, the share it gallops over rather than walks, against the number of values, at 4,096 keys a list, for uniform values and Zipf 1 and 1.5. Uniform: 1 14%, 2 15%, 4 18%, 8 28%, 16 43%, 32 60%, 64 75%, 128 86%, 256 54%, 512 0%, 1,024 0%, 2,048 0%, 4,096 0%, 8,192 0%. Zipf 1: 1 14%, 2 15%, 4 18%, 8 28%, 16 43%, 32 60%, 64 71%, 128 47%, 256 16%, 512 6%, 1,024 6%, 2,048 5%, 4,096 5%, 8,192 5%. Zipf 1.5: 1 14%, 2 15%, 4 18%, 8 28%, 16 43%, 32 49%, 64 41%, 128 23%, 256 22%, 512 21%, 1,024 19%, 2,048 20%, 4,096 19%, 8,192 22%.00.2500.5000.7501values the keys are drawn fromequal runs galloped, of all met12481632641282565121K2K4K8KZipf 1.5Zipf 1uniform4,096 keys a listshare galloped
Fig. 6 The share of the equal runs the bar meets that it gallops, against the number of values, at 4,096 keys a list, uniform and under Zipf 1 and 1.5. Uniform: 86% at 128 values, none at 1,024. Zipf 1: 6% at 1,024 values.

The bar gallops where galloping pays and stops where it does not: on uniform values it gallops 86% of the equal runs it meets at 128 values and none at 1,024; under Zipf 1 it gallops 6% of them at 1,024 values. The 6% is the point. Under a Zipf law nearly every run a merge meets is a rare value’s short run, and the few it gallops are the common values’ runs, which hold a large share of the keys. The bar finds them without knowing which values are common, by noticing that a run has gone on for seven equal answers.

That is a different kind of adaptivity from the one the earlier pages measured. When galloping pays and the floor when the values repeat treated the input’s run lengths as a property of the input, to be known or estimated before choosing a merge; the bar treats them as a property of each run, discovered while merging it, and makes the choice once a run. A threshold on the mean run is the right rule only when the runs are all alike.

What the bar costs on a run

The bar’s cost on any one run can be written down, and it explains both its small losses and its large gains. A run of rr equal keys in each list costs rr comparisons to walk, one for every two keys placed, and about 4log⁡2r+14 \log_2 r + 1 to gallop, by the earlier page’s count. The bar walks the first bb equal answers and gallops the rest, so it pays about b+4log⁡2(r−b)+1b + 4 \log_2(r - b) + 1 on a run longer than its bar and exactly the walk’s rr on a run shorter. On a run of five hundred keys with a bar of seven that is about forty-four comparisons where galloping from the start costs thirty-seven, a fifth more; on a run of three it is three, where galloping costs about eight.

So the bar is never far from the better merge on any single run, and it is the better merge on runs of mixed lengths, because it pays the cheaper price for each. On uniform values with few values, where every run is long, it pays the first bb answers of every run for nothing, which is the few thousandths it loses to galloping there. On uniform values near the crossing, where every run is about as long as a gallop’s break-even, both prices are about the same, which is why it neither gains nor loses. Under a Zipf law the runs are of every length at once, and the bar’s choice per run is worth a quarter.

The bar moves, but on these lists it does not move far. It falls when a gallop extends a run by at least the bar, and on a list of common values that happens on most gallops, so there the bar falls toward one; on rare values it never gallops, and the bar stays where it was. Seven, Timsort’s starting value, was chosen for runs of distinct keys from two lists, where a gallop’s break-even is about where it is here, and the sort the library ships found the library’s constants tuned for the inputs the library expects. The plates suggest the same constant serves for equal runs, and none of these lists tested a different starting value.

The floor this does not reach

The merge that can say equal solved the game exactly at four keys a list and found the counting floor met by a merge that answers “equal”. These lists are thousands of keys long, too long to solve, and none of the four merges is claimed to be optimal on them. How close anything gets to the floor measured sorts by their distance from the bound nothing can cross; a merge of Zipf-distributed lists has such a bound too — the logarithm of the number of interleavings consistent with the lists’ value counts — and how far above it the bar sits under Zipf 1 is the measurement this page did not make. The bar is a quarter under the better of two merges, which is a statement about those merges, not about the floor.

What these lists leave out

Equal answers only. The bar here counts consecutive equal answers. Timsort’s own bar counts consecutive wins of one list over the other, which is how it gallops over long stretches of distinct keys in which one list’s keys all come first. These lists have that structure too, wherever two adjacent values each have long runs, and a merge using both bars was not measured.

One law of interleaving. The ranks are assigned to values at random, so long and short runs alternate in no order. A law whose common values come first — a list of priorities, say — would give the history rule the long runs together and might rescue it; the bar does not depend on the order, any more than the pattern that defeats the pattern found pdqsort’s pattern-breaking needed to know which pattern it faced.

Comparisons only. Every cost is comparisons. A gallop also moves a run whole where a walk moves it a key at a time, and the moves were not counted; the floor a merge cannot reach is the reminder that a merge’s comparisons and its moves are two different floors.

Still open: one bar for equal answers and wins

Timsort gallops when one list wins repeatedly, the bar here when the lists tie repeatedly, and a merge of repeated values meets both: a long run of one value in one list facing a short run in the other is a stretch of wins, and two long runs of the same value are a stretch of ties. Each bar sees one kind of stretch and walks the other.

The measurement that follows gives the merge both bars, sharing one count of consecutive answers of either kind — ties or wins by the same list — and one bar that moves as either kind of gallop pays or fails, and runs it on the same lists, uniform and skewed, at every length. The prediction is that it gains a further tenth over the equal-answer bar under Zipf 1, from the stretches where one list holds a common value’s long run and the other a few of its keys, and changes nothing on uniform values, where such stretches are no longer than the ties. It could fail on the shared bar: a gallop over wins and a gallop over ties pay at different run lengths, since a tie places two keys a comparison and a win one, and a bar tuned by one may be wrong for the other. The question is whether a merge needs one bar or two, or whether the kind of stretch it is in matters less than how long the stretch has already lasted.

Named alongside this one

Essays reaching for the same objects. Nobody chose these; they are what the concept index makes visible.

The objects this essay names

Each one links to every other essay that touches it.

Average caseComparison countEqual elementsGallopingMerge sortPredictionZipf distribution