核心概述:基于 __gnu_pbds::gp_hash_table 的高性能哈希表,API 大体兼容 unordered_map,约 3x 更快、1.5x 内存,初始容量需为 2 的幂。
原文引述:
Description: Hash map with mostly the same API as unordered_map, but \tilde 3x faster. Uses 1.5x memory. Initial capacity must be a power of 2 (if provided).
展开阐述:
- 定义与适用场景
- 提供近似 unordered_map 接口的哈希表替代,优化常数性能,适合大规模键值存取、计数、去重等高性能需求场景。
- 在竞赛与工程实践中针对构造冲突的鲁棒性与吞吐更敏感时更具优势。
- 接口与数据结构字段说明(据实现习惯)
- 类型:__gnu_pbds::gp_hash_table<Key, T, chash>,可指定初始容量(必须为 2 的幂)。
- 自定义哈希 chash:
- 常量 C = ll(4e18 * acos(0)) | 71,为大奇数常量;
- 返回 __builtin_bswap64(x * C),扩大有效位参与度(避免仅低位参与)。
- 变体:x ^ RANDOM 形式以加入随机扰动,增强防 hack(注释“or other places where hacking might be a problem”)。
- 核心操作与流程要点
- put/get/erase 接口与 unordered_map 大体一致;遍历、迭代器语义相似。
- 初始化时若能估计元素规模,传入接近的容量(2 的幂)可减少重哈希次数。
- 复杂度与边界条件
- 平均期望 O(1);常数更优但使用内存约 1.5x。
- 初始容量不为 2 的幂将违背约束,应显式对齐为 2^k。
- 对抗性数据:建议使用带 RANDOM 的哈希变体,降低构造冲突风险。
- 实现细节与坑
- 请勿在同一容器上混用不同 chash 定义;保持 hash 函数稳定性。
- 注意 key 的可哈希性与等价比较一致性。
- 预留容量时传入合适的 2 的幂,避免频繁 rehash。
- 变体/扩展
- 若键为 pair/自定义结构,可在 chash 中做混合哈希(按注释原则“多位参与、扰动随机化”)。
- 若需有序统计或按秩访问可使用 010-数据结构-顺序统计树;若只需计数/频率统计,亦可与 003-数据结构-树状数组 搭配处理离散秩到频率的映射。
- 正确性与工程直觉
- 增强位扩散与随机扰动可显著降低碰撞集中度;容量为 2 的幂与位操作实现细节相匹配,保证高效寻址。