为什么stl :: map中的查找比我的应用程序中的stl :: vector慢?

时间:2010-07-07 13:40:17

标签: performance stl visual-c++-2008

我有点吃惊,特别是在阅读this之后。

我用

template <class T>
int GetPosition(vector<T> mVec, T element)
{
    return find(mVec.begin(), mVec.end(), element) - mVec.begin();
}

template <class T>
int GetPosition(map<T, int> mMap, T element)
{
    return mMap.find(element)->second;
}

作为模板函数,用于获取向量分析列表中特定元素的索引。

元素是对象的唯一指针,我想从中检索索引。

然后我在for循环中使用此模板

for(int i = 0; i < myCount; i++)
{
  index = GetPosition(myVector, elements[i]) //or GetPosition(myMap, elements[i])
}

虽然我收集的所有信息都建议使用地图,但地图实施速度要慢几个数量级: 57 ms使用矢量变量在比较70000ms时使用地图。

这里有些东西被严重堵塞,但我不知道是什么。你呢?

开发平台是Windows XP上的MS VS 2008 Standard sp1

3 个答案:

答案 0 :(得分:3)

注意,当您的代码写在此处时,您将按值传递向量和地图,即,您在每次调用时重建每个代码的新副本。这显然压倒了搜索的时间。

尝试:

template <class T> 
int GetPosition(const map<T, int> &mMap, T element) 

答案 1 :(得分:3)

由于您是按值传递的,因此您在每次通话中都会处理vectormap。我觉得这让结果变得毫无意义。

将它们作为参考或const参考传递并再次运行测试。

template <class T>
int GetPosition(const vector<T>& mVec, T element)
{
    return find(mVec.begin(), mVec.end(), element) - mVec.begin();
}

template <class T>
int GetPosition(const map<T, int>& mMap, T element)
{
    return mMap.find(element)->second;
}

答案 2 :(得分:1)

除了使用引用来避免副本,正如其他答案所提到的那样,这里的算法复杂性也存在差异。

查找大小为n的(未排序的)向量具有O(n)时间复杂度,而地图上的相同操作具有O(log n)时间复杂度。

简单地解释一下,这意味着在向量中查找对象需要时间K1 * n,而地图需要K2 * log(n)时间,其中K1和K2是一些取决于向量实现的常量和地图。

在实践中哪个更快取决于容器的大小和常数(我认为可以肯定K1会更快。

缓存一致性之类的东西也将在这里发挥作用,如果你的容器很小,一切都将在向量的缓存中,而不是地图。 (使用缓存,常量也不会真正保持不变,但这是另一个故事......)