193. Vec::with_capacity — Size Up Front, Skip the Realloc Churn
A Vec you push into one element at a time doesn’t grow one element at a time — it doubles, copying every existing item to a fresh allocation each time it outgrows its buffer. If you already know how many items are coming, Vec::with_capacity buys the whole buffer once.
The hidden cost of push
Vec::new() starts with zero capacity. As you push, it reallocates geometrically — roughly doubling each time — and every reallocation copies all existing elements into the new, larger buffer. Fill a vector with 1000 items and you pay for that copying around ten times over:
| |
In a hot loop, that churn is pure waste: allocate, copy, free, allocate bigger, copy again.
Reserve the space once
If you know the final size, hand it to Vec::with_capacity. The buffer is allocated a single time, and push never has to move it:
| |
Capacity is not length: with_capacity(1000) gives you room for 1000 items but the vector is still empty (len() == 0) until you push.
Already have a Vec? Use reserve
When the vector exists and you’re about to add a known number of elements, reserve grows the buffer ahead of time without touching the contents:
| |
Use reserve before a batch of pushes; use reserve_exact when you want the buffer sized precisely, with no geometric slack.
collect often does this for you
Iterators expose a size_hint, so collecting from a sized iterator already reserves the right capacity — no manual call needed:
| |
The win is biggest exactly where it matters: tight loops building large vectors. If you can name the size, name it once and let push run free.