正确插入应优先用 try_emplace() 避免冗余构造;查找只读场景必须用 find() 而非 operator[];预调 reserve() 减少 rehash;自定义 key 需特化 hash;小数据量时 map 可能更快。
直接用 operator[] 赋值看似简单,但会默认构造 value 类型对象再赋值,对非 trivial 类型(比如含自定义构造函数的类)可能引发不必要开销或逻辑错误。更安全高效的做法是用 insert() 或 try_emplace()。
insert({key, value}):先构造 pair,再插入;若 key 已存在,整个插入失败,且已构造的 value 不会被销毁(有临时对象开销)try_emplace(key, args...):仅当 key 不存在时才用 args... 原地构造 value,避免拷贝/移动,推荐用于复杂 value 类型emplace(key, value) 不是标准用法——emplace() 接收的是 key 和 value 的构造参数,不是已有对象,误写成 emplace(k, v) 可能触发隐式转换或编译失败operator[] 在 key 不存在时会插入一个默认构造的 value,这在只读场景下是严重副作用。真正做“查找”就该用 find() ——它返回 iterator,查不到就是 end(),零副作用。
find()
at(key) 比 operator[] 更安全(越界抛 std::out_of_range)count(key) 仅返回 0 或 1,适合布尔判断,但内部仍要哈希+遍历桶,性能略低于 find()(后者拿到迭代器后还能继续用)
unordered_map 性能退化往往不是因为“哈希慢”,而是桶数不足导致链表过长,或频繁 rehash 触发大量元素重散列。默认负载因子上限是 1.0,一旦平均每个桶超过 1 个元素,就会触发 rehash。
reserve(N) 预分配桶空间(不是元素空间),可大幅减少 rehash 次数;N 应略大于预期最大元素数std::hash 特化,否则编译不过;若哈希函数分布差(如所有 key 哈希值相同),查找退化为 O(n)别只记“unordered_map 平均 O(1),map 是 O(log n)”——实际中 cache 局部性、数据规模、key 类型都会反转结论。
unordered_map 哈希计算成本可能高于 map 的几次指针比较lower_bound):只能选 map;unordered_map 迭代器不保证顺序,也不能按 key 区间遍历真正影响性能的,往往是哈希函数质量、负载因子控制、以及是否意外触发了 rehash——这些比“选哪个容器”更值得花时间检查。