Ce face std::unordered_map::reserve
O tabelă hash are un număr de găleți (bucket_count()). load_factor() este media de elemente pe găleată: size() / bucket_count(). Când aceasta ar depăși max_load_factor() (implicit 1.0), tabela face un rehash: alocă mai multe găleți și redistribuie toate elementele. Rehash-ul costă și invalidează toți iteratorii.
reserve(n) alege dinainte destule găleți pentru n elemente fără să depășească max_load_factor(), deci nu vor mai fi rehash-uri până la n elemente. Numărul exact de găleți ales depinde de bibliotecă (libc++ preferă numere prime); valorile de mai jos sunt cele de pe libc++.
Parametri
| Parametru | Descriere |
|---|---|
n |
Numărul de elemente pentru care se pregătește tabela. |
Ce returnează
reserve: nimic. bucket_count: numărul de găleți. load_factor: elemente pe găleată, ca float.
Exemple
Exemplul 1: Găleți și grad de încărcare
#include <print>
#include <unordered_map>
int main() {
std::unordered_map<int, int> m;
std::println("gol: buckets={} load={}", m.bucket_count(), m.load_factor());
m.reserve(100);
std::println("după reserve: buckets={} load={}", m.bucket_count(), m.load_factor());
for (int i = 0; i < 50; ++i) {
m[i] = i * i;
}
std::println("50 elemente: buckets={} load={:.3f} max={}", m.bucket_count(), m.load_factor(), m.max_load_factor());
}
Rezultat
gol: buckets=0 load=0
după reserve: buckets=101 load=0
50 elemente: buckets=101 load=0.495 max=1
Exemplul 2: Câte rehash-uri evită reserve
#include <print>
#include <unordered_map>
int rehashuri(bool cu_reserve) {
std::unordered_map<int, int> m;
if (cu_reserve) {
m.reserve(10000);
}
int numar = 0;
auto galeti = m.bucket_count();
for (int i = 0; i < 10000; ++i) {
m[i] = i;
if (m.bucket_count() != galeti) {
++numar;
galeti = m.bucket_count();
}
}
return numar;
}
int main() {
std::println("Fără reserve: {} rehash-uri", rehashuri(false));
std::println("Cu reserve: {} rehash-uri", rehashuri(true));
}
Rezultat
Fără reserve: 13 rehash-uri
Cu reserve: 0 rehash-uri
Greșeli frecvente
- Confunzi
reserve(n)al tabelei hash cu cel al vectorului: aicinînseamnă elemente, nu găleți. Pentru un număr de găleți, existărehash(numar_galeti). - Te bazezi pe valori exacte ale lui
bucket_count(). Ele diferă între biblioteci (libc++, libstdc++, MSVC).
Comenzi înrudite
std::unordered_map: Dicționar bazat pe tabelă hash: căutare în timp mediu constant, dar fără o ordine anume a elementelor.std::vector::reserve: reserve() rezervă memorie pentru n elemente, capacity() spune cât loc este rezervat, iar shrink_to_fit() cere eliberarea locului nefolosit.std::unordered_set: Mulțime de valori unice bazată pe hash: verificare „există?” în timp mediu constant, fără ordine.