非性能敏感场景下std::pair哈希函数的合理实现咨询
关于
std::pair哈希函数的问题解答 1. 简单异或哈希在你的场景下是否合理?
完全合理。你的场景属于极低负载、低查询频率:容器规模最多两三百条,每秒仅数百次查询,这种量级下,就算异或哈希存在缺陷,实际影响也微乎其微:
- 异或的缺陷(比如
pair(a,b)和pair(b,a)哈希值相同、部分位碰撞概率略高)在小数据量下几乎不会触发,就算出现冲突,unordered_map的冲突处理逻辑也能轻松应对,性能损失可以忽略。 - 针对
pair<int,int>这类默认哈希为恒等函数的情况,就算出现(1,2)和(2,1)的哈希冲突,两三百条数据里出现这类情况的概率极低,且查询时的比较成本可以忽略。 - 针对
pair<string,string>,只要std::hash<string>性能良好,异或的计算成本极低,完全适配你的查询频率需求。
简言之,你的场景下这种异或实现足够用,完全没必要过度优化。
2. 非性能敏感场景的合理哈希组合方式
如果不想用boost::hash_combine那种复杂位操作,又想比单纯异或更稳健,推荐几种简单易实现的方案:
- 移位+异或:通过移位打破对称值的哈希碰撞,操作成本极低:
std::size_t operator()(auto const& k) const noexcept { std::hash<T> hT; std::hash<U> hU; return (hT(k.first) << 1) ^ hU(k.second); } - 直接加法:代码直观无复杂操作,冲突概率比单纯异或低:
注:std::size_t operator()(auto const& k) const noexcept { std::hash<T> hT; std::hash<U> hU; return hT(k.first) + hU(k.second); }size_t是无符号类型,加法溢出相当于自动取模,无需额外处理。 - 轻量版哈希组合:仅保留少量位操作,简化
boost实现,兼顾稳健性与简洁性:std::size_t operator()(auto const& k) const noexcept { std::hash<T> hT; std::hash<U> hU; std::size_t ret = hT(k.first); ret ^= hU(k.second) + (ret << 3) + (ret >> 2); return ret; }
这些方案都无需复杂操作,同时能有效降低冲突概率,适合非性能敏感但想要稍好稳健性的场景。
内容的提问来源于stack exchange,提问作者ABu
相关产品推荐
相关产品推荐

