继上篇,上文的 5bit 占位算法,平均查一次需要计算 5 次哈希函数,效率不行。
我在想,既然数据库用户密码哈希都能加盐,那么 hashmap 优化也是可以加的,同一个 key ,加了不同的盐后,计算出的哈希值是完全不一样的,既可以避免冲突,也能提升查找效率。
具体算法还是很简单,以查找一个英文字典举例:
1. 分配一个比数据量要大一点的桶数组。
2. 依次遍历原始字符串,把当前字符串 hash 后的结果,保存到对应的桶 ID 里。
3. 如果目标桶被占用了,那么换一个盐或者种子 ID ,一直到找到空余的桶。
4. 依次处理完所有数据。
这样就构建结束,由于加了盐,那么查找 key 的时候,也需要同时把 key 对应的种子 ID 也附带传进去。
我用 VS2022 写了一点点性能测试代码,对一个字典查找 8 千万次,在 release 下编译。
如下图所示,由于完美哈希没有一个冲突,查找效率明显要比标准的 stl 好很多。

我在想,既然数据库用户密码哈希都能加盐,那么 hashmap 优化也是可以加的,同一个 key ,加了不同的盐后,计算出的哈希值是完全不一样的,既可以避免冲突,也能提升查找效率。
具体算法还是很简单,以查找一个英文字典举例:
1. 分配一个比数据量要大一点的桶数组。
2. 依次遍历原始字符串,把当前字符串 hash 后的结果,保存到对应的桶 ID 里。
3. 如果目标桶被占用了,那么换一个盐或者种子 ID ,一直到找到空余的桶。
4. 依次处理完所有数据。
这样就构建结束,由于加了盐,那么查找 key 的时候,也需要同时把 key 对应的种子 ID 也附带传进去。
我用 VS2022 写了一点点性能测试代码,对一个字典查找 8 千万次,在 release 下编译。
如下图所示,由于完美哈希没有一个冲突,查找效率明显要比标准的 stl 好很多。

