我正在寻找一些具有固定键(在初始化期间固定)并且查找速度更快的地图。它可能不支持以后添加/更新元素。是否有一些算法可以查看键列表并制定一个函数,以便以后查找更快。在我的例子中,键是字符串。
更新
在编译时不知道密钥。但在应用程序的初始化时间。以后不会再进行任何插入,但会有很多查找。所以我想要优化查找。
答案 0 :(得分:2)
CMPH可能就是你要找的东西。基本上这是gperf
,而需要在编译时设置。
虽然C ++ 11当然可以std::unordered_map
,但也可能会发生一些冲突。
因为你查找字符串,对于字符串,trie(任何不同的trie风格,暴击位或任何时髦的名字)也值得研究,特别是如果你有很多他们。免费提供许多免费的实施方案 尝试的优点是它们可以索引压缩字符串,因此它们使用更少的内存,这使得在缓存中具有数据的可能性更高。访问模式也随机性较小,这也是缓存友好的。哈希表必须存储值加上哈希值,并且或多或少随机地索引(不是随机,但不可预测)到内存中。理想情况下,类似trie / trie的结构只需要一个额外的位来区分每个节点中的密钥和它的公共前缀。
(注意O(log(N))在这种情况下很可能比O(1)快,因为big-O不会考虑这样的事情。)
答案 1 :(得分:1)
请注意,这些是截然不同的事情:您是否需要上限,是否需要快速的典型费率,或者您是否需要最快的查询,没有问题?最后一个将花费你,前两个可能是相互冲突的目标。
您可以尝试基于输入创建完美的哈希函数(即没有输入集冲突的哈希函数)。这是一个以某种方式解决的问题(例如this,this)。但是,它们通常会生成源代码,并且可能会花费大量时间生成散列函数。
对此的修改将使用通用散列函数(例如,shift-multiply-add)并对合适的参数进行强力搜索。
这需要与一些字符串比较的成本进行折衷(如果你不必整理,那就不会非常昂贵)。
另一个选择是使用两个不同的哈希函数 - 这会增加单个查找的成本,但与外星人窃取你的时钟周期相比,降级的可能性略小。这不太可能是典型字符串和一个体面的散列函数的问题。
答案 2 :(得分:0)
尝试google-sparsehash:http://code.google.com/p/google-sparsehash/
An extremely memory-efficient hash_map implementation. 2 bits/entry overhead!
The SparseHash library contains several hash-map implementations, including
implementations that optimize for space or speed.
答案 3 :(得分:0)
在类似的主题(编译时已知的(项目数)项目中),我制作了这个:Lookups on known set of integer keys。开销低,不需要完美的哈希。幸运的是,它在C; - )