我会看到使用std :: map而不是vector <pair <string,string =“”>&gt;?</pair <string,>的性能提升

时间:2012-10-02 18:35:57

标签: c++ stl stdvector stdmap

我目前有一些代码,我使用vector pair<string,string>。这用于存储来自XML解析的一些数据,因此,该过程在某些地方非常慢。在尝试加快整个过程的过程中,我想知道从vector<pair<string,string> >切换到std::map<string,string>是否会有任何性能优势?我可以编写代码并运行一个分析器,但我想我会看到我是否能得到一个答案,表明首先会有一些明显的性能提升。我不需要进行任何排序,我只是将项添加到向量中,然后在稍后阶段迭代内容并进行一些处理 - 我不需要排序或任何这种性质。我猜测也许我不会获得任何性能提升,但我之前从未实际使用过std::map所以我不知道如果没有要求或编码全部。

5 个答案:

答案 0 :(得分:10)

没有。如果(正如您所说)您只是在对集合进行迭代,那么您将使用std::map看到一个小的(可能无法衡量的)性能减少

地图用于按键访问值。如果你从不这样做,那么map对于容器来说是一个糟糕的选择。

答案 1 :(得分:6)

如果您没有修改vector<pair<string,string> > - 只是一遍又一遍地重复它 - 您将通过使用map来降低性能。这是因为典型的map由二进制对象树组织,每个对象都可以分配在不同的内存块中(除非您编写自己的分配器)。另外,map的每个节点都管理指向邻居对象的指针,因此它也是时间和内存开销。但是,按键搜索是O(log)操作。另一方面,vector将数据保存在一个块中,因此处理器缓存通常会感觉更好。在向量中搜索实际上是O(N)操作,这不是很好但可以接受。可以使用lower_bound等函数将已排序的向量中的搜索升级到O(日志)。

这取决于您对此数据所做的操作。如果你做了很多搜索 - 可能最好使用像unordered_map这样的散列容器,因为在这个容器中按键搜索是O(1)操作。对于迭代,如上所述,vector更快。

可能值得替换string中的pair,但这在很大程度上取决于您在那里持有的内容以及访问容器的方式。

答案 2 :(得分:5)

答案取决于您对这些数据结构的处理方式以及它们的大小。如果您的std::vector<std::pair<std::stringm std::string> >中有数千个元素,并且您一遍又一遍地搜索first元素,那么使用std::map<std::string, std::string>可能会提高性能(您可能需要考虑使用{{1}对于这个用例,相反)。如果你的向量相对较小并且你不想过于频繁地将元素插入中间,那么使用向量可能会更快。如果你只是迭代元素,矢量比地图快很多:迭代并不是他们的力量之一。地图擅长查找,假设元素的数量不是很小,因为否则对矢量的线性搜索仍然更快。

确定花费时间的最佳方法是对代码进行分析:在预先花费时间的情况下,通常并不完全清楚。通常,可疑的热点实际上没有问题,其他区域显示出意想不到的性能问题。例如,您可能会将对象传递给我的值,而不是通过引用传递给某个不起眼的地方。

答案 3 :(得分:1)

如果您的使用模式在执行任何查找之前执行了许多插入,那么您可能会受益于实现“延迟”映射,其中元素按需排序(即,当您获取迭代器,执行查找等时)。

答案 4 :(得分:0)

由于C ++在线性内存中说std::vector个排序项,所以首先它分配一个具有初始容量的内存块,然后当你想要将新项插入向量时,它将检查它是否有更多空间如果不是,它将分配一个具有更多空间的新缓冲区,将所有项目复制到新缓冲区中,然后删除源缓冲区并将其设置为新缓冲区。

当您刚开始将项目插入vector并且您有很多项目时,您会遇到太多的重新分配,复制构造和析构函数调用。

为了解决这个问题,如果你现在计算输入项(不精确但是通常的长度),你可以reserve向量的一些内存,避免重新分配和所有事情。 如果您不知道大小,可以使用像std::list这样的集合,从不重新分配其内部项目。