String::shrink_to_fit¶
Level: reference · for working programmers
One line: Gives back the spare capacity, dropping it to about len() — usually by reallocating and copying.
Stable since 1.0.0.
It is not free. Shrinking generally means asking the allocator for a smaller block and copying the bytes into it, so calling it in a loop or on a string that will grow again is worse than leaving the slack alone.
The right moment is once, when a string reaches its final size and will be kept for a long time — parsed configuration held for the process lifetime, a million interned names.
The resulting capacity is len() or greater: the allocator is free to keep it larger, and after this the guarantee is only that it is no bigger than before.
For a string that is genuinely finished, into_boxed_str is the stronger move: it shrinks and drops the capacity field entirely, saving eight more bytes per value.
Example¶
string_shrink_to_fit.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.
fn main() {
let mut s = String::with_capacity(64);
s.push_str("small");
println!("before len {} capacity {}", s.len(), s.capacity());
s.shrink_to_fit();
println!("after len {} capacity {}", s.len(), s.capacity());
// Contents are untouched; only the bookkeeping changed.
println!("{s:?}");
// The stronger move for a finished string.
let mut done = String::with_capacity(64);
done.push_str("final");
let boxed = done.into_boxed_str();
println!("Box<str> is {} bytes vs String's {}",
std::mem::size_of_val(&boxed), std::mem::size_of::<String>());
// Shrinking then growing again undoes the saving and costs two copies.
let mut churn = String::with_capacity(32);
churn.push_str("ab");
churn.shrink_to_fit();
let low = churn.capacity();
churn.push_str("cdefgh");
println!("{low} -> {}", churn.capacity());
}
Verified output of string_shrink_to_fit.rs — regenerated by tools/run_examples.py, never hand-typed.
See also¶
String::shrink_to— shrinking to a floor rather than to lenString::into_boxed_str— shrink and drop the capacity fieldString::capacity— what this reducesString::reserve— the opposite direction
String::shrink_to_fit in the standard library ↗
Po polsku¶
Oddanie zapasu nie jest darmowe: shrink_to_fit zwykle prosi alokator o mniejszy blok i przepisuje do niego bajty, więc wywołanie go w pętli albo na łańcuchu znaków, który zaraz znowu urośnie, kosztuje dwa kopiowania zamiast zera — w przykładzie pojemność (capacity) spada z 32 do 2 i natychmiast wraca do 8. Właściwy moment jest tylko jeden: gdy tekst osiągnął ostateczny rozmiar i będzie trzymany długo — sparsowana konfiguracja żyjąca przez cały czas działania procesu, milion nazw w tablicy symboli. Gwarancja jest przy tym słabsza, niż podpowiada nazwa: wynikowa pojemność to len() albo więcej, bo alokator ma prawo zostawić ją wyższą. A jeśli łańcuch jest naprawdę skończony, mocniejszym ruchem jest into_boxed_str — kasuje samo pole pojemności i zamienia 24 bajty String na 16 bajtów Box<str>.
Szukaj po polsku: pojemność a długość łańcucha znaków · zwalnianie nadmiarowej pamięci · rust String shrink_to_fit · rust into_boxed_str