The measurement: where the list loses, and where it wins
Here is what it printed. Your numbers should match — -seed 42, n = 100,000.
$ algo playlist -in big.jsonl -from 47 -to 3
move 47 -> 3 in a library of 100000
walk/shift pointer writes
slice (shift) 44 0
Playlist (ours) 50 4
container/list 50 (hidden)
The list lost. Not narrowly — it lost, even though its move really did cost only four pointer writes, exactly as promised.
The reason is in the walk column. To reach nodes 47 and 3 the list took 50
hops. The array had nowhere to walk — it knows where element 47 is — so all it
had left to do was shift 44 elements.
The O(1) move is real. But you have to walk O(n) to reach it, and that walk costs more than the shifting did.
Where it gets absurd
$ algo playlist -in big.jsonl -from 500 -to 499
walk/shift pointer writes
slice (shift) 1 0
Playlist (ours) 999 4
container/list 999 (hidden)
Moving an item one position: one shift for the array, 999 hops for the list. A thousand times the work in order to perform the "more efficient" O(1) operation.
And where the list wins
Every number above assumes one thing: that the position has to be found. But a user dragging a playlist entry is not searching — they are already holding the track. The same measurement without the search:
$ algo playlist -in big.jsonl -from 99000 -to 50
walk/shift pointer writes
slice (shift) 98950 0
Playlist (ours) 99050 4
and if you ALREADY HOLD the node (a drag-and-drop UI does):
slice (shift) 98950 0
Playlist (ours) 0 4
98,950 against 4. Twenty-four thousand times. That is what a linked list is for.
The rule
A linked list's O(1) is real, but it starts from a node, not from a position. If you still have to find the position, you have already paid O(n) — and paid more than the plain shift would have cost.
That is why a linked list is almost never used alone. It is used alongside an index that hands you the node directly — a hash table (lesson 10). Then you get both: O(1) to find and O(1) to move.
It is the first time in this course that two structures cooperate rather than compete. It is not the last.
The container/list numbers match ours to within one hop, because it is the same
structure. The standard library does not make walking cheaper — walking is a
property of the structure, not of the implementation. A good implementation of
the wrong choice is still the wrong choice.