The crossover: four answers
Now compare your guess with the measurement.
$ algo sweep -ints
key: int32 layout: contiguous
n | lin cmps bin cmps | lin ns/op bin ns/op | winner by CLOCK
-------|-----------------------|---------------------------|----------------
2 | 2 2 | 2 3 | LINEAR
4 | 3 2 | 3 3 | binary
8 | 5 3 | 3 3 | binary
16 | 9 4 | 4 4 | binary
32 | 17 5 | 5 4 | binary
127 | 65 7 | 22 7 | binary
1024 | 513 10 | 112 5 | binary
2254 | 1128 11 | 265 6 | binary
The counter and the clock disagree
Look at n = 4: 3 comparisons against 2, and identical times. At n = 8 the counter says binary is 1.7× better; the clock says they are level. The gap only opens much later.
By comparisons, binary wins almost immediately. By the clock, only from n ≈ 6.
Neither is lying. They measure different things:
- a comparison is the unit Big-O counts;
- time depends on what one comparison costs, on whether the data is already in the processor's cache, and on whether the processor can predict where the next jump goes.
A linear scan walks the array in order. The processor sees that pattern coming and fetches ahead. A binary search jumps: n/2, n/4, 3n/4 — and every jump is unpredictable.
So 65 predictable comparisons can take less time than 7 unpredictable ones.
And there is more than one answer
Run the same sweep with a different layout and key:
| configuration | crossover |
|---|---|
-ints, contiguous (this page) |
n ≈ 6 |
-ints -scattered (through a map, like a real index) |
n ≈ 6, but both ~2× slower |
without -ints (strings, expensive comparison) |
n ≈ 3 |
With strings, one comparison is a function call that may walk several bytes. When comparisons get expensive, the linear scan — which makes n/2 of them — loses sooner.
Three mechanisms, each of which moves the crossover: memory layout, the cost of one comparison, and how well the processor predicts branches.
Four answers to one question
transit measured this question two ways and got two answers. We measured it a
third time and got a third:
| measurement | crossover |
|---|---|
transit, synthetic contiguous array |
≈ 50 |
transit, real timetable, their machine |
> 127 (linear still winning) |
transit's benchmark, our machine |
< 127 (binary winning) |
| this lesson, our machine | ≈ 6 |
From 6 to more than 127. A twentyfold spread for the same algorithm.
transit's synthetic run used a fresh contiguous []int32 sitting in cache; its
real index reaches the same kind of array through a 1,514-entry map. Layout
decided the winner, not the algorithm.
Your number will be the fifth
Run algo sweep on your own machine. You will almost certainly get a different
number again.
That is not a mistake. That is the answer.
If your crossover differs from the one printed here, you have not done anything wrong — you have reproduced the actual finding: the crossover is not a property of the algorithm. It is a property of your data, your layout and your processor.
The skill this lesson is after is not the number 50 or 127. It is being able to find yours.
The one number that does not move is the comparison count: 11 comparisons for 2,254 items, wherever you run it. That is why this course counts operations. But the decision about which search to use is made by the clock — and the clock has to be run on your own machine.