What the libraries do

A table with one draw in each cell

A rule that prices every number of merging rounds for a library merge sort's late tail was right within 6% everywhere except the first round, which it priced 15% to 25% wrong at the three smallest buffers, with the sign changing between buffers. A second calibration table made of exactly what the first round produces — two sorted pieces merged into a run of twice the buffer — was predicted to bring that error under 6%. It does not: priced from the pair table the first round is still 4.5% to 24.1% off, because two sorted pieces merged are a sorted run of twice the buffer, the object the first table already held. The error was the table's single draw per cell. A run of twice the buffer crosses the head with a coefficient of variation of 0.21, ten times a run of one buffer's; averaged over sixteen draws, every round at every buffer is priced within 5.6%. A smaller, systematic error at the long rounds of short reaches survives the averaging, and so does the one partway miss.

Every number of rounds, priced is the latest step in a strand about one practical decision inside the sort the library ships. Given a file that is sorted except for a late tenth, the library’s merge sort, working with a buffer of fixed size, sorts the tail a buffer’s worth at a time into pieces, and then either sends each piece into the long sorted head, merges the pieces in pairwise rounds first and sends the larger groups, or merges all the way to one group. The head each piece will meet built a rule that prices those choices before making any of them, from two tables measured once on synthetic inputs: what a round of merging random pieces costs, and what a sorted run of a given length costs to cross a head whose top AA keys it interleaves with.

The rule priced every number of rounds within about 6% of its measured cost — except one. The first round was priced 15.3% low at a buffer of a 256th, 14.7% high at a 1,024th and 25.1% low at a 4,096th. The rule survived it, because one round was never close to the cheapest, but an estimate that is wrong by a quarter in a direction that changes from one buffer to the next is not one a rule should be built on.

That essay’s explanation was that the first round is where the table’s assumption is least true. A group after one round is two pieces merged into a run of twice the buffer, the first size too long to be merged inside the buffer, so it crosses the head by rotation, the dearest and most variable move the library merge makes. Its closing section proposed calibrating exactly that: a second table made of two sorted pieces of a buffer each, merged into a run of twice the buffer, crossing a head at each AA. It predicted the first round’s error would fall under 6%. And it named the alternative: that the error was about where the file’s groups sit relative to the head, which no synthetic table can know.

Which half of the first round is wrong

A round’s price has two parts: the round’s own merging, priced from a measured merge of random pieces, and the resulting groups’ crossing of the head, priced from the crossing table. Before building any new table it is worth knowing which part carries the error.

The first round's own merge is priced to the hundredth — 0.149 against 0.149, 0.147 against 0.147, 0.139 against 0.140 moves a key — and all of its error is the pairs' crossing of the head: priced 3.81, 20.96, 48.88 against a measured 4.69, 18.17, 65.39, of which rotation is 2.60, 10.38, 37.16One round of merging at buffers of 1/256, 1/1024, 1/4096, reach a fifth: moves a key of the round's own merge (priced from merges of random pieces, and measured) and of the groups' crossing of the head (priced from the published table, and measured, with the rotation share of the measured). 1/256: merge 0.149 priced, 0.149 measured; crossing 3.809 priced, 4.692 measured (rotation 2.598); 1/1024: merge 0.147 priced, 0.147 measured; crossing 20.959 priced, 18.166 measured (rotation 10.377); 1/4096: merge 0.139 priced, 0.140 measured; crossing 48.875 priced, 65.386 measured (rotation 37.157).buffer 1/256merge, measured 0.149merge, priced 0.149crossing, measured 4.69crossing, priced 3.81buffer 1/1024merge, measured 0.147merge, priced 0.147crossing, measured 18.17crossing, priced 20.96buffer 1/4096merge, measured 0.140merge, priced 0.139crossing, measured 65.39crossing, priced 48.88moves a key, one round; thin bar under the measured crossing: its rotationreach a fifthmerge against crossing
Fig. 1 One round of merging at the three smallest buffers, split into the round’s own merge and the groups’ crossing of the head, priced and measured. The merge is priced to within a thousandth of a move a key; the crossing is where every per cent of the error lives, and most of the crossing is rotation.

The round’s own merge is priced to within a thousandth of a move a key at all three buffers: 0.149 priced against 0.149 measured at a 256th, 0.147 against 0.147 at a 1,024th, 0.139 against 0.140 at a 4,096th. The whole of the error is the crossing. At a 4,096th the groups’ crossing is priced at 48.9 moves a key and measured at 65.4, of which 37.2 is rotation; at a 1,024th it is priced at 21.0 and measured at 18.2.

So the question is entirely about the crossing table, and about how it prices a run of twice the buffer.

The pair table, built as proposed

The proposal’s table draws, for each AA, the keys a run will hold and the head it will cross; sorts two pieces of a buffer each; merges them with the library merge into one run; and then counts the moves of that run crossing the head. Only the crossing is counted, since the pair’s own merge is the round’s cost and already priced exactly.

The first round's pricing error at the three smallest buffers: -15.3%, 14.7%, -25.1% from the published table, -4.5%, -24.1%, -21.8% from a table of pairs built as proposed, and -0.2%, -4.5%, 1.6% from a table whose every cell is the mean of 16 drawsA file of 65,536 keys whose late tenth reaches a fifth of the way in, at buffers of 1/16, 1/32, 1/64, 1/128, 1/256, 1/1024, 1/4096: the priced estimate of moves a key with one round of merging, over the measured, minus one, for three readings of the crossing table. 1/16: published 0.0%, pair 0.0%, mean 0.0%; 1/32: published 4.9%, pair 4.8%, mean 3.0%; 1/64: published -0.2%, pair -4.3%, mean 3.6%; 1/128: published 1.3%, pair -4.9%, mean -0.7%; 1/256: published -15.3%, pair -4.5%, mean -0.2%; 1/1024: published 14.7%, pair -24.1%, mean -4.5%; 1/4096: published -25.1%, pair -21.8%, mean 1.6%. Dashed: ±6%.-20%-10%10%20%buffer 1/16buffer 1/32buffer 1/64buffer 1/128buffer 1/256buffer 1/1024buffer 1/4096published table (one draw a cell)pair table, as proposedmean of 16 draws a cellreach a fifth, first rounddashed: ±6%
Fig. 2 The first round’s pricing error at every buffer from three tables: the published one, the pair table built as proposed, and a table whose every cell is the mean of sixteen draws. Only the third keeps every buffer inside the dashed band.

Priced from the pair table, the first round’s error at the three smallest buffers is −4.5%, −24.1% and −21.8%. At a 256th it improved; at a 1,024th it went from 14.7% high to 24.1% low; at a 4,096th it barely moved. The prediction fails, and not by a small amount.

The reason is visible in what the pair table’s run is. Two sorted pieces of random keys, merged, are a sorted run of twice the buffer of random keys — exactly the object the published table already draws when it prices a run of that length. A merge does not leave a mark on the keys it merged. The pair table could only ever differ from the published one by being another draw of the same random experiment, and that is what it is: a different seed, a different answer, an error of the same size in a different direction.

That points at the explanation neither the essay nor its proposal considered. Every cell of the published table is one synthetic run. If one run’s crossing varies a lot from draw to draw, the table’s cells are wrong by about that much, in directions that change from cell to cell, and an estimate read from them inherits it.

How much one draw varies

One draw of a run's crossing varies most at exactly twice the buffer — a coefficient of variation of 0.20, 0.21, 0.22 at the three smallest buffers — against 0.00, 0.02, 0.03 for a run of one buffer, 0.04, 0.05, 0.05 for eight and 0.01, 0.01, 0.01 for thirty-two: the first round's groups are the runs a single draw prices worstA sorted run of k buffers of random keys crossing a head whose top 8 × (run length) keys it interleaves with, file of 65,536 keys, 16 draws each: the standard deviation of the moves over their mean. 1/256: 1× 0.00 (published draw 1.00 of the mean), 2× 0.20 (published draw 1.18 of the mean), 4× 0.11 (published draw 0.91 of the mean), 8× 0.04 (published draw 0.99 of the mean), 16× 0.03 (published draw 0.99 of the mean), 32× 0.01 (published draw 1.00 of the mean); 1/1024: 1× 0.02 (published draw 0.97 of the mean), 2× 0.21 (published draw 0.89 of the mean), 4× 0.08 (published draw 1.01 of the mean), 8× 0.05 (published draw 1.01 of the mean), 16× 0.02 (published draw 0.99 of the mean), 32× 0.01 (published draw 1.01 of the mean); 1/4096: 1× 0.03 (published draw 1.03 of the mean), 2× 0.22 (published draw 1.18 of the mean), 4× 0.09 (published draw 1.02 of the mean), 8× 0.05 (published draw 1.06 of the mean), 16× 0.02 (published draw 1.03 of the mean), 32× 0.01 (published draw 0.99 of the mean).00.1000.200the run's length, in bufferscoefficient of variation of one crossing, over 16 draws1×2×4×8×16×32×buffer 1/1024buffer 1/4096buffer 1/256a run of k buffers, A = 8 × its length16 draws
Fig. 3 The coefficient of variation of one run’s crossing over sixteen draws, against the run’s length in buffers, at the three smallest buffers. The peak is at exactly two buffers — the length of the first round’s groups.

It varies a great deal, and at exactly the run length the first round produces. A run of one buffer crosses the head with a coefficient of variation of 0.00 to 0.03 across sixteen draws: it fits in the buffer, the merge is a sequence of shifts, and its cost is close to a function of AA. A run of twice the buffer varies with a coefficient of 0.20 to 0.22. A run of four buffers is at 0.08 to 0.11, eight at 0.04 to 0.05, and thirty-two at 0.01.

The worst buffer shows what that does to a price. At a 4,096th the published table’s cells for a run of two buffers, at AA of one, eight and sixty-four times the run’s length, hold 0.98, 1.18 and 0.74 of their own sixteen-draw means. A price read by interpolating between cells like those can land anywhere in a band a fifth either side of the truth, and the first round’s price there landed a quarter low. Nothing systematic was being priced in that cell; a few unlucky draws were, and the rule read them as the cost of a pair.

The shape is what the library merge’s own mechanism predicts. A run longer than the buffer cannot be merged by shifting through the buffer, so the merge splits the work and rotates blocks of keys into place, and each rotation’s length depends on where the run’s keys happen to fall among the head’s. A run of exactly two buffers is cut into the fewest pieces, so its cost is decided by one or two rotations whose lengths are whatever the draw made them. A run of thirty-two buffers is cut into many, and many rotations average out. The variance is not a property of pairs. It is a property of runs that have only just become too long for the buffer.

At a buffer of 1/1024 the 16 draws of a run of twice the buffer crossing its head range from 0.75 to 1.33 times their mean, and the published table's draw is 0.89; a run of one buffer stays within 0.96–1.02 and a run of eight within 0.95–1.13Buffer 1/1024 (64 keys), file of 65,536 keys: each draw of a sorted run of k buffers crossing a head whose top 8 × (run length) keys it interleaves with, divided by the mean of 16 draws. 1× (64 keys, mean 629 moves): 0.97, 0.97, 1.02, 1.00, 1.00, 1.01, 1.00, 1.01, 1.00, 1.01, 1.00, 1.01, 0.96, 1.00, 1.02, 1.01; 2× (128 keys, mean 2,511 moves): 0.89, 0.87, 1.31, 1.31, 0.88, 0.88, 1.30, 0.88, 1.31, 0.76, 0.88, 0.89, 0.75, 1.33, 0.88, 0.89; 4× (256 keys, mean 8,861 moves): 1.01, 1.02, 1.02, 1.02, 0.84, 1.01, 1.15, 1.01, 0.98, 1.01, 1.02, 1.14, 1.01, 0.85, 1.02, 0.88; 8× (512 keys, mean 24,276 moves): 1.01, 0.96, 1.06, 0.97, 1.13, 0.97, 1.02, 0.95, 1.07, 0.98, 0.98, 0.95, 0.98, 0.96, 1.01, 1.02. The first draw of each is the published table's.0.6×0.8×1.2×1.4×meanrun of 1 bufferrun of 2 buffersrun of 4 buffersrun of 8 buffersfaint: the other draws · ringed: the published drawbuffer 1/1024draw over mean
Fig. 4 The sixteen draws of one cell at a buffer of a 1,024th, as multiples of their mean, for runs of one, two, four and eight buffers. The ringed draw is the one the published table holds.

At a buffer of a 1,024th the sixteen draws of a run of two buffers crossing its head range from 0.75 to 1.33 times their mean, and the published table’s draw at that cell is 0.89. Runs of one buffer stay within 0.96 to 1.02, and runs of eight within 0.95 to 1.13. A table holding one draw from a spread of 0.75 to 1.33 is a table that is right to about a fifth, and that is the size of error the first round showed.

Nothing about the file was involved. The alternative the proposal named — that the groups’ position relative to the head was being mispriced — would have needed an error that averaging synthetic runs could not remove. Averaging removes it.

A table of means

Priced from the mean of 16 draws a cell, every number of rounds at every buffer is within 5.6% of its measured cost, against 25.1% for the published table, and the first round is no longer the outlier; the cheapest number of rounds chosen is unchanged at all seven buffersThe late tail reaching a fifth of the way in: the estimate from the mean table over the measured, minus one, at every number of rounds and buffer (lines), with the published table's first-round errors as rings. 1/16: 0 0.5%, 1 0.0% (chosen 0, cheapest 0); 1/32: 0 0.8%, 1 3.0%, 2 0.2% (chosen 0, cheapest 0); 1/64: 0 1.5%, 1 3.6%, 2 2.6%, 3 0.0% (chosen 0, cheapest 0); 1/128: 0 2.3%, 1 -0.7%, 2 3.9%, 3 1.8%, 4 1.7% (chosen 0, cheapest 0); 1/256: 0 3.0%, 1 -0.2%, 2 -0.9%, 3 1.4%, 4 1.3%, 5 0.6% (chosen 5, cheapest 5); 1/1024: 0 -0.3%, 1 -4.5%, 2 1.1%, 3 4.4%, 4 2.8%, 5 1.1%, 6 0.2%, 7 -0.2% (chosen 7, cheapest 7); 1/4096: 0 -5.6%, 1 1.6%, 2 -3.0%, 3 -2.1%, 4 3.5%, 5 2.8%, 6 2.2%, 7 0.7%, 8 0.5%, 9 0.2% (chosen 9, cheapest 9).-0.20000123456789rounds of mergingpriced over measured, minus onebuffer 1/128buffer 1/256buffer 1/32buffer 1/4096buffer 1/64buffer 1/16buffer 1/1024rings: the published first rounddashed: ±6%
Fig. 5 Every number of rounds at every buffer priced from a table whose cells are the mean of sixteen draws, against its measured cost, with the published table’s first-round errors ringed. All of it sits inside the dashed band.

With every cell the mean of sixteen draws, the first round is priced −0.2%, −4.5% and +1.6% off at the three smallest buffers, and every number of rounds at every buffer is within 5.6% of its measured cost, against 25.1% for the published table. The first round is no longer the outlier; the largest remaining error is no rounds at all at a 4,096th, −5.6%, where 410 pieces of sixteen keys each are priced one at a time and a small bias in the smallest runs’ cells adds up.

The rule’s choices do not change. At every one of the seven buffers it picks the same number of rounds from the mean table as from the published one, and both are the cheapest measured: none from a 16th to a 128th, all from a 256th down. That half of the proposal’s prediction held exactly, for the reason it gave: the first round was never close to the cheapest, so pricing it better changes no choice.

The size of what remains is about what sixteen draws should leave. A cell whose single draw varies with a coefficient of 0.21 has a mean of sixteen draws that varies with about a quarter of that, 0.05, and the worst error left anywhere in the plate is 5.6%. The table is now as good as its sample size, and the sample size is now the thing to choose: halving the remaining error would take sixty-four draws a cell, and the cells where a draw barely varies — runs of one buffer, runs of sixteen or more — would gain nothing from any of them.

A sixteenfold table costs sixteen times as much to build, once. The table is measured on synthetic inputs before any file is sorted, so the cost is paid at calibration and not per sort; the rule reads the same number of cells either way.

Across reaches

The main input’s late tail reaches a fifth of the way into the head’s keys. The earlier essay also ran four other reaches, and the one partway optimum it found was at the shortest.

Across five reaches and three buffers the first round is priced within 6% in 2 of 15 settings from the published table and 13 from the mean table; the largest error left, 17.1% at a reach of 0.7 and a buffer of 1/128, does not average away, and the one partway miss — 5 rounds for 6 — staysFor each reach of the late tail and buffers of 1/128, 1/256, 1/1024: the first round's pricing error from the published table and from the mean of 16 draws, and the rounds chosen from the mean table against the cheapest measured. reach 0.1, 1/128: published -7.4%, mean -3.9%; chose 0, cheapest 0; reach 0.1, 1/256: published 6.0%, mean 4.7%; chose 0, cheapest 0; reach 0.1, 1/1024: published 11.6%, mean 3.4%; chose 5, cheapest 6; reach 0.2, 1/128: published 1.3%, mean -0.7%; chose 0, cheapest 0; reach 0.2, 1/256: published -15.3%, mean -0.2%; chose 5, cheapest 5; reach 0.2, 1/1024: published 14.7%, mean -4.5%; chose 7, cheapest 7; reach 0.4, 1/128: published 14.1%, mean 14.7%; chose 4, cheapest 4; reach 0.4, 1/256: published 9.7%, mean 5.2%; chose 5, cheapest 5; reach 0.4, 1/1024: published 21.8%, mean 0.8%; chose 7, cheapest 7; reach 0.7, 1/128: published 16.7%, mean 17.1%; chose 4, cheapest 4; reach 0.7, 1/256: published 24.3%, mean 5.8%; chose 5, cheapest 5; reach 0.7, 1/1024: published 21.7%, mean 0.6%; chose 7, cheapest 7; reach 1, 1/128: published -16.6%, mean -6.0%; chose 4, cheapest 4; reach 1, 1/256: published 20.4%, mean 2.2%; chose 5, cheapest 5; reach 1, 1/1024: published 27.9%, mean 5.6%; chose 7, cheapest 7.reach 0.1reach 0.2reach 0.4reach 0.7reach 1buffer 1/128buffer 1/256buffer 1/1024-7.4%-3.9%6.0%4.7%11.6%3.4%1.3%-0.7%-15.3%-0.2%14.7%-4.5%14.1%14.7%9.7%5.2%21.8%0.8%16.7%17.1%24.3%5.8%21.7%0.6%-16.6%-6.0%20.4%2.2%27.9%5.6%upper: published table · lower: mean of 16 draws · outlined: still outside 6%fifteen settingsfirst round's error
Fig. 6 The first round’s error at five reaches and three buffers, from the published table (upper figure in each cell) and the mean of sixteen draws (lower). Dark cells are still outside 6% after averaging.

From the published table the first round is within 6% in only 2 of the 15 settings; from the mean table, in 13. The errors that survive the averaging are systematic. At a buffer of a 128th the first round is priced 17.1% high with the tail reaching 0.7 of the way in and 14.7% high at 0.4. No number of draws changes those, because they are not draws: at that buffer and those reaches the pairs’ actual crossing differs from what a random run of the same length and the same AA costs, which is the alternative the proposal named, present after all, but smaller and in fewer places than the first round’s error suggested.

The partway miss survives too. With the tail reaching a tenth of the way in, at a 1,024th, six rounds of seven are cheapest and the rule chooses five from either table, because the last two rounds are priced 6% and 12% high whichever table is read. That error was never noise: it sits in long groups, where one draw varies by a per cent or two, and it is the same systematic mispricing of groups that barely reach into a head, now isolated from the noise that had been lying on top of the first round.

Two errors that looked like one

The first round had looked like one error with one cause. It was two.

The larger part was noise: a calibration table with one draw a cell, at the one run length where a draw varies by a fifth. It changed sign between buffers because each buffer’s cells were different draws, it was largest at the first round because that is where variance peaks, and it disappears under averaging. The pair table could not touch it, because the pair table is the same random experiment drawn again.

The smaller part is bias: places where the file’s groups cross the head differently from a random run with the same length and the same count of head keys above its smallest. It appears at a buffer of a 128th with the tail reaching far into the head, and at the long final rounds of a tail that barely reaches in. It survives averaging because it is not about the draw but about the arrangement, and a synthetic table indexed by length and AA alone does not know the arrangement.

A result the size of its own noise is the general version of the first half: a difference smaller than the spread of the thing being measured is not a difference, and here the spread was hiding inside a calibration rather than inside a result. The earlier essay compared estimates to measurements to the tenth of a per cent and never asked how much its own table would move if it were measured again.

What a calibration table owes

The habit this strand has followed since the rotation that could be priced is to price a decision from measurements of the operation itself rather than from a model of it. That habit is right, and it carries an obligation the strand had not met: a measured table is an estimate, and its cells need error bars. A cell measured once is one sample of a quantity whose spread the table does not record; where the spread is small — runs that fit the buffer, runs of many buffers — one sample is enough, and where it is a fifth, one sample produces a rule whose estimates are wrong by a fifth for reasons nobody can see in the rule.

The fix measured here is crude: the same number of draws in every cell. A table could spend its draws where the spread is, many at twice the buffer and one at thirty-two times, and reach the same accuracy for a fraction of the cost. Pieces that fit the buffer and the moves no stable sort can skip both found that the library merge’s costs turn on a few structural thresholds; the variance plate says the same about its predictability, which changes abruptly at the threshold where a run stops fitting.

What was not measured

The bias’s cause. The systematic errors at a 128th and at the long final rounds are located and sized, not explained. Both involve groups whose keys’ positions among the head’s are far from what a random run would have: at long reaches the tail’s later groups face a head already enlarged by earlier groups, and at short reaches the final groups are long against a narrow band of head keys.

Other file lengths. Every number is for a file of 65,536 keys with a late tenth, as in the earlier essays.

Comparisons. Every cost is moves of keys, as the library merge counts them.

A guarantee that depends on an allocation is the reminder that the buffer, which decides where every threshold above falls, is chosen by the library from the memory it is given and not from the input.

Still open: the arrangement a table cannot see

The bias that survived is in two places, and both are groups crossing a head that is not the head a random run would face: at long reaches, a head enlarged by groups merged before; at short reaches, long groups against a narrow band of head keys. The crossing table is indexed by a run’s length and the count of head keys above its smallest key, and it assumes the run’s keys are spread at random through that band.

The measurement that follows adds one index to the table: how the run’s keys are spread through the band — the share of them in the band’s upper half — measured on the file’s own groups by the same binary searches the rule already makes, and calibrated on synthetic runs drawn with that spread. The prediction is that the systematic errors at a 128th fall from 14.7% and 17.1% to under 6%, and that the partway miss is corrected, since the last two rounds’ groups are the ones whose keys crowd the top of a narrow band. It could fail if the spread is not the variable — if what matters is how the run’s keys clump between individual head keys, which one share cannot describe. The question is whether a cost that depends on arrangement can be priced from one more number about the arrangement, or whether the only faithful calibration of a run is the run.

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.

Auxiliary spaceData movementMeasurementMerge sortPredictionRotationStable sort