何时在std :: map上选择std :: vector作为键值数据?

时间:2010-04-27 15:19:12

标签: c++

考虑到在主内存中搜索时缓存和数据位置的积极影响,我倾向于使用std::vector<>std::pair<> - 类似于键值项,并对两者执行线性搜索,如果我知道关键值项目的总量永远不会“太大”而不会严重影响绩效。

最近我遇到过很多情况,事先我知道我拥有大量的键值项,因此从一开始就选择了std::map<>

我想知道如何在上述情况下为正确的容器做出决定。

  • 始终使用std::vector<>(或类似)?
  • 始终使用std::map<>(或类似)?
  • 对项目计数范围中哪一个比另一个更优选有一种直觉?
  • 完全不同的东西?

谢谢!

5 个答案:

答案 0 :(得分:7)

我很少使用std::vector进行线性搜索(除了如下所述的二进制搜索)。我认为只需要足够少的数据就可以了,但是如果数据量很少,那么任何事情都不可能提供巨大的优势。

根据使用模式,std::vector上的二进制搜索可能有意义。当您需要在使用期间定期更新数据时,std::map效果很好。但是,在很多情况下,您加载一些数据然后使用数据 - 但是在加载数据之后,它大部分都是静态的(即,如果有的话,它变化很小)。

在这种情况下,将数据加载到矢量中,必要时对其进行排序,然后对数据进行二进制搜索(例如std::lower_boundstd::equal_range)会很有意义。这提供了两个世界中最好的 - 低复杂度二进制搜索从高位置引用的良好缓存使用(即,向量是连续的,而不是{{的链接结构) 1}})。当然,缺点是插入和删除速度很慢 - 但这是我用过你原来的想法的一次 - 分别存储新插入的数据,直到达到某个极限,然后才将其与其余部分一起排序。数据,因此单个搜索包括对数据主体的二进制搜索,然后线性搜索(少量)新插入的数据。

答案 1 :(得分:4)

我永远不会仅仅根据(可能是虚假的)“效率”理由做出选择,但总是根据我实际上要对容器做的事情。我想存储重复项吗?插入顺序重要吗?我有时会想要搜索价值而非关键吗?那种事。

答案 2 :(得分:2)

我几乎总是喜欢使用map(或者当散列容器更有意义时使用unordered_map)和vector。

话虽如此,我认为你的推理是倒退的。当存在大量数据时,我倾向于使用向量 ,因为向量将占用较小的内存。

使用正确类型的数据集,您可以加载一个向量,然后对其进行排序,并使用较小的占用空间和类似的性能特征对其进行二元搜索,尤其是在加载后数据集稳定的情况下。

答案 3 :(得分:2)

您是否考虑过使用排序数据结构?他们倾向于提供对数搜索和插入 - 合理的权衡。就个人而言,除了喜欢地图之外我没有任何硬性和快速的规则,因为它能够键入人类可读/可理解的值。

当然,关于地图与列表/向量(已排序和未排序)的效率也有很多讨论 - 如果您的密钥是10,000个字符的字符串,则进行字符串比较可能需要更长时间才能搜索到只列出几个项目,因此您需要确保能够有效地比较密钥。

答案 4 :(得分:1)

为什么不考虑unordered_map