244. clone_from — Reuse the Buffer You Already Have Instead of Reallocating
*dst = src.clone() throws away dst’s heap buffer and allocates a brand-new one every time. dst.clone_from(&src) copies into the storage dst already owns — reusing its capacity instead of freeing and re-grabbing it.
The hidden allocation in assignment
Cloning into an existing variable looks free, but it isn’t:
| |
src.clone() builds a completely new String with its own allocation, then the assignment drops the old dst — buffer and all. In a loop that runs thousands of times, that’s a free-then-allocate churn on every iteration, even when the old buffer was plenty big.
clone_from copies into place
| |
Clone::clone_from is a provided trait method whose whole job is “make self equal to source, reusing self’s resources where possible.” For String and Vec, that means copying the bytes into the buffer that’s already there and only reallocating if it’s too small. The default impl just does *self = source.clone(), but the collections override it to reuse storage.
Where it pays off: the reused accumulator
The classic win is a buffer you refresh every pass through a loop — pair it with the reuse-one-buffer pattern:
| |
Every clone_from after the first reuses whatever capacity scratch grew to, so the loop stops hammering the allocator. Swap in scratch = row.clone() and you’re back to a fresh allocation on each turn.
It works for any nested owned type too — a Vec<String> clones each element with clone_from, so inner buffers get reused, not rebuilt. Whenever you catch yourself writing dst = src.clone() for a dst you already own, clone_from is the version that doesn’t throw the buffer away.