我有一张约100,000对的地图。有没有什么方法可以在使用find()时加快搜索速度,因为键是按字母顺序排列的。我该怎么做呢。我知道您可以在创建地图时指定新的比较器。但是这会加速find()函数吗?
提前致谢。
[已解决]感谢一群人我决定使用矢量并使用低和上限来“剪切”一些搜索。
我也是新来的,有没有办法将这个问题标记为已回答,或选择最佳答案?
答案 0 :(得分:11)
如果一个不同的比较器能够更快地进行比较(对于字符串通常会非常困难),它只会加速查找。
如果您基本上按顺序插入所有数据,然后进行搜索,则使用std::vector
std::lower_bound
或std::upper_bound
可能会更快。
如果您不关心订购,并且只想尽快找到数据,您可能会发现std::unordered_map
更适合您。
编辑:仅供记录:您可能“找到”或“可能找到”这些内容的方式通常是通过分析。根据情况,它可能足够快,即使在简单的测试中也很明显,因此分析不是必需的,但如果有(很多)怀疑,或者你想量化效果,分析器可能是正确的方法这样做。
答案 1 :(得分:4)
std::map
已经在利用密钥按字母顺序排列的事实 - 它保证了自己。您无法通过更改比较器来改进它(假设它已经是一个相当有效的字符串比较)。
您是否考虑在C ++ 11之前的各种实现中使用unordered_map
(又名hash_map
?它应该能够在O(1)而不是O(log(n))中搜索{ {1}}。
你也可以看一些更具异国情调的东西,比如特里,但这不是标准库的一部分,所以你要么必须在别处找一个或者自己动手,所以我建议std::map
是一个很好的起点。
答案 2 :(得分:4)
如果您使用std::find
查找元素,则应切换为使用map::find
(您的问题中没有真正说过。)map::find
使用地图这一事实命令搜索得更快。
如果仍然不够好,您可能会查看一个哈希容器,例如unordered_map
而不是map
。
答案 3 :(得分:2)
我已经对unordered_map
进行了投票,但我还想提出另一个观点。
可能会影响现代机器性能的一个原因是缓存使用不当。地图将在整个地方分配节点,并且参考的位置不会太多。此外,由于它必须在节点之间存储一堆指针,因此会占用更多内存。
在最近的Going Native 2012会议上,Bjarne Stroustroup提出了一个interesting talk来讨论这个话题。他将vector
和list
性能与涉及大量随机插入和删除的任务进行了比较,其中list
似乎应该占主导地位,但由于内存大小和布局问题{ {1}}实际上是迄今为止最快的。从幻灯片43开始,查看his slides。
vector
可让您直接访问该元素,因此它可能意味着在内存中跳转的次数比尝试将数据保留在unordered_map
中更少(因此性能优于vector
所以我的评论只是一个警告,要始终牢记你的记忆访问模式以提高性能