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

发布于 2024-09-08 15:53:47 字数 873 浏览 0 评论 0原文

我有点震惊,尤其是在阅读这个之后。

我使用

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 毫秒,相比之下使用地图 70000 毫秒。

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

开发平台为MS VS 2008 Standard sp1,Windows XP

I am kind of startled, especially after reading this.

I use

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

and

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

as template functions to get the index of a specific element in my vector respectivly list.

Elements are unique pointers to objects, of which i want to retrieve the index off.

I then use this template in a for-loop like

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

While all bits of information i gathered suggested to use a map, the map implementation is several orders of magnitude slower: 57 ms using the vector variant in comparision 70000ms using the map.

Something is severly borked here, but i do not know what. Do you?

Development plattform is MS VS 2008 Standard sp1, on windows XP

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

山川志 2024-09-15 15:53:47

由于您是按值传递它们,因此您在每次调用时都会处理 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;
}

Since you are passing them by value, you are coping the vector and map in every call you are making. I'd sat that this makes the results pretty much meaningless.

Pass them as reference or const reference and run the test again.

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;
}
千秋岁 2024-09-15 15:53:47

请注意,当您的代码写在这里时,您将按值传递向量和映射,即,您将在每次调用时重建每个向量和映射的新副本。这显然压垮了搜索时间。

尝试:

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

Note, as your code is written here, you are passing both the vector and the map by value, i.e., you are rebuilding new copies of each on every call. That's clearly overwhelming the time of the search.

try:

template <class T> 
int GetPosition(const map<T, int> &mMap, T element) 
纸短情长 2024-09-15 15:53:47

除了像其他答案提到的那样使用引用来避免复制之外,这里的算法复杂性也存在差异。

在大小为 n 的(未排序)向量中查找的时间复杂度为 O(n),而在映射上执行相同操作的时间复杂度为 O(log n)。

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

在实践中哪个更快取决于您的容器的大小和常量是什么(我认为可以肯定地说 K1 会更快。

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

Aside from using references to avoid copies as the other answers mention, there's also a difference in algorithmic complexity here.

Look-up in (non-sorted) vector of size n has O(n) time complexity, whereas the same operation on the map has O(log n) time complexity.

Simply explained, it means that looking up an object in your vector takes time K1*n while it takes K2*log(n) time for the map, where K1 and K2 are some constants that depend on the implementation of the vector and map.

Which is faster in practice depends on the size of your container and what the constants are (I think it's safe to say K1will be faster.

Things like cache coherence will also come into play here, if your container is small everything will be in the cache for the vector but not for map. (With a cache, the constants won't really be constant either, but that's another story...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文