Watch the capacity grow
Create stats.go (see the panel). It adds two commands: algo load and
algo stats -growth.
stats -growth appends one item at a time and prints the slice header every
time cap changes. Each of those lines is one fresh array and one full copy.
How a Go slice actually grows
$ algo stats -growth -n 1000
append len cap items copied
1 1 1 0
2 2 2 1
3 3 4 2
5 5 8 4
9 9 18 8
19 19 36 18
37 37 73 36
74 74 146 73
147 147 292 146
293 293 585 292
586 586 1024 585
1000 appends, 11 reallocations, 1165 items copied in total
average copies per append: 1.165
The textbook says "the capacity doubles". Look at the numbers: 1, 2, 4, 8, 18, 36, 73, 146, 292, 585, 1024.
Eighteen, not sixteen. Seventy-three, not seventy-two. One thousand and twenty-four, not one thousand one hundred and seventy.
Go doubles only at the start. Past a few hundred elements it grows by roughly 1.25×, and then rounds the result up to an allocator size class. The textbook rule is an approximation; the real behaviour is the one you just measured.
What "amortized" actually costs
One number answers the whole question. Grow n and watch the last line:
| n | reallocations | items copied | average per append |
|---|---|---|---|
| 1,000 | 11 | 1,165 | 1.165 |
| 10,000 | 19 | 35,540 | 3.554 |
| 100,000 | 29 | 456,253 | 4.563 |
| 1,000,000 | 39 | 4,467,696 | 4.468 |
Two things are visible immediately.
The average stops growing. 100,000 and 1,000,000 give almost the same
answer — about 4.5 copies per append. That is amortized O(1): the average
is constant. If append were really O(n) you would see about 500,000 at a
million, not 4.5.
But the constant is not 1. It is ~4.5, and that follows directly from the 1.25 growth factor: if capacity grows by a factor g, each element is copied about 1/(g−1) times on average, and 1/(1.25−1) = 4.
"Amortized O(1)" does not mean free. It means constant. The constant is something you can measure — and you just did.
The reallocation count grows logarithmically: 11, 19, 29, 39 — about ten more for each factor of ten in n. A thousand times the data costs twenty extra reallocations, not a thousand.