在 c++ 中加速 map<string,int> .find() 的最快方法。其中键按字母顺序排列
Fastest way to speed up map<string,int> .find() in c++ . Where the keys are in alphabetical order
我有一张大约有100000对的地图。如果键是按字母顺序排列的,那么在使用find()时,有什么方法可以加快搜索速度吗。还有我应该怎么做。我知道你可以在创建地图时指定一个新的比较器。但是这会加快find()函数的速度吗?
提前谢谢。
[解决]感谢大家,我决定使用向量,并使用下界和上界来"剪切"一些搜索。
我也是新来的,有没有办法把这个问题标记为已回答,或者选择一个最佳答案?
不同的比较器只有在能够更快地进行比较的情况下才能加快查找速度(对于字符串来说,这通常非常困难)。
如果你基本上是按顺序插入所有数据,然后进行搜索,那么将std::vector
与std::lower_bound
或std::upper_bound
一起使用可能会更快。
如果您并不真正关心订购,只想尽快找到数据,您可能会发现std::unordered_map
更适合您。
编辑:只是为了记录:你"可能会发现"或"可能会找到"这些东西的方式通常是通过分析。根据具体情况,它可能足够快,即使在简单的测试中也很明显,所以分析并不是真正必要的,但如果有(很多)疑问,或者你想量化效果,分析程序可能是正确的方法。
std::map
已经利用了键按字母顺序排列的事实——它本身就保证了这一点。您无法通过更改比较器来改进它(假设它已经是一个相当有效的字符串比较)。
您是否考虑过使用unordered_map
(在C++11之前的各种实现中也称为hash_map
)?它应该能够在O(1)而不是O(log(n))中搜索std::map
。
你也可以研究一些更具异国情调的东西,比如trie,但这不是标准库的一部分,所以你要么在其他地方找到一个,要么自己推出,所以我建议unordered_map
是一个很好的起点。
如果您使用std::find
来查找元素,则应该切换到使用map::find
(您在问题中并没有真正说明。)map::find
使用了这样一个事实,即映射的搜索速度要快得多。
如果这还不够好,您可以查看一个散列容器,例如unordered_map
,而不是map
。
我已经投了unordered_map
的票,但我也想提出另一点。
影响现代机器性能的因素之一是缓存使用不当。地图会在各处分配节点,并且不会有太多的参考位置。此外,由于它必须在节点之间存储一堆指针,它将占用更多的内存。
在最近的Going Native 2012会议上,Bjarne Stroustroup做了一个有趣的演讲,谈到了这个话题。他比较了vector
和list
在涉及大量随机插入和删除的任务中的性能,其中list
似乎应该占主导地位,但由于内存大小和布局问题,vector
实际上是迄今为止最快的。看看他的幻灯片,从第43张幻灯片开始。
unordered_map
允许您直接访问元素,因此这可能意味着与尝试将数据粘贴在vector
中相比,在内存中的跳跃更少(因此性能比vector
更好),因此我的评论只是一个警告,要始终记住您的内存访问模式,以提高性能
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- C++优先级队列,按对象的唯一指针的特定方法升序排列
- 按对象的特定方法按升序排列的C++优先级队列
- 有没有一种 STL 方法可以找到字符串的所有排列,给出一个以 C++ 为单位的大小?
- 基于整数向量执行位排列的有效方法?
- 列出 n 个对象的所有 k 排列的有效方法,同时满足特定标准
- 获得给定向量的排列索引列表的最佳方法是什么?
- 是否有一种记忆有效的方法来探索从输入排列产生的解决方案
- 使用不同方法的排列函数的运行速度会导致意外结果
- 我编写了一个C++程序来打印单词字母的排列.我想知道是否有其他更简单的方法可以做到这一点
- 在 c++ 中加速 map<string,int> .find() 的最快方法。其中键按字母顺序排列
- 计算在不进行排列的情况下递归相加为N的方法的数量
- 使函数接受其参数列表的任意排列的规范方法是什么?