So, these types [the growable array, C++ and this library call them "vector", Rust calls them Vec, a lot of the GC languages call this ArrayList or even plain List] have the amortized constant time append operation which they achieve via a growth factor, often doubling. However, as the programmer we might well know useful things about how big our growable array will be, either immediately or in its eventual future, this won't influence correctness but responding appropriately can have a large impact on performance. To use this knowledge, the type should provide a reservation API - a way to tell it what you know.

There are several ways you could arrange this, but some of them can't optimize certain scenarios practically. I call Rust's choice here a "bifurcated" API because it has two functions named `reserve` and `reserve_exact` where many provide only one (typically named `reserve` but analogous to `reserve_exact`)

Because we know the circumstance, we can use the amortized growth strategy where appropriate in `reserve` even though we don't use it for `reserve_exact`.

Suppose I'm receiving bundles of Doodads, to form a Shipment, I can see how many Doodads are in the bundle I received, but I only know it's the last bundle of the shipment or it's not, I don't have advance notice of the full size of the Shipment.

If I receive bundles of 10, 15, 11, 20, 9, 14 and finally 13 Doodads. Total shipment size was 92 Doodads.

With just naive doubling, we grow to 1, 2, 4, 8, 16, 32, 64 and finally 128 Doodads space, we perform 127 copies + 92 new writes = 219 Doodad writes, 8 heap allocations. That's our base case, it's what Bjarne Stroustrup recommends and what you'd get in many languages out of the box or if you've never used a reservation API.

If we abuse Vec::reserve_exact - as might be tempting if it's the only API - we grow 10, 25, 36, 56, 65, 79, 92, we perform 271 copies + 92 new writes = 363 Doodad writes, 7 heap allocations, one fewer allocation but many more copies, probably slightly worse. Ouch.

If we use the bifurcated API we grow 10, 25, 50, 100, we perform 85 copies + 92 new writes = 177 Doodad writes, 4 allocations, we're doing markedly better.