我哪种情况会比排序的std::><vector<std:std::p air<A,B>>更快?

I which situation will std::map<A,B> be faster than sorted std::vector<std::pair<A,B>>?

本文关键字:lt std gt air 更快 vector 情况 排序      更新时间:2023-10-16

我在某些代码中使用了map来存储有序数据。我发现对于巨大的地图,破坏可能需要一段时间。在我有的这段代码中,将map替换为vector<pair>将处理时间减少了 10000...

最后,我

非常惊讶,我决定将map表演与排序vectorpair进行比较。

我很惊讶,因为我找不到mappair的排序vector快的情况(随机填充并稍后排序(......一定有一些情况map更快。否则提供这门课有什么意义?

这是我测试的内容:

测试一个,比较map填充和销毁与vector填充、排序(因为我想要一个分类容器(和销毁:

#include <iostream>
#include <time.h>
#include <cstdlib>
#include <map>
#include <vector>
#include <algorithm>
int main(void)
{
    clock_t tStart = clock();
    {
        std::map<float,int> myMap;
        for ( int i = 0; i != 10000000; ++i )
        {
            myMap[ ((float)std::rand()) / RAND_MAX ] = i;
        }
    }
    std::cout << "Time taken by map: " << ((double)(clock() - tStart)/CLOCKS_PER_SEC) << std::endl;
    tStart = clock();
    {
        std::vector< std::pair<float,int> > myVect;
        for ( int i = 0; i != 10000000; ++i )
        {
            myVect.push_back( std::make_pair( ((float)std::rand()) / RAND_MAX, i ) );
        }
        // sort the vector, as we want a sorted container:
        std::sort( myVect.begin(), myVect.end() );
    }
    std::cout << "Time taken by vect: " << ((double)(clock() - tStart)/CLOCKS_PER_SEC) << std::endl;
    return 0;
}

g++ main.cpp -O3 -o main编译并得到:

Time taken by map: 21.7142
Time taken by vect: 7.94725

map慢了3倍...

然后,我说,"好吧,矢量填充和排序更快,但使用地图搜索会更快"......所以我测试了:

#include <iostream>
#include <time.h>
#include <cstdlib>
#include <map>
#include <vector>
#include <algorithm>
int main(void)
{
    clock_t tStart = clock();
    {
        std::map<float,int> myMap;
        float middle = 0;
        float last;
        for ( int i = 0; i != 10000000; ++i )
        {
            last = ((float)std::rand()) / RAND_MAX;
            myMap[ last ] = i;
            if ( i == 5000000 )
                middle = last; // element we will later search
        }
        std::cout << "Map created after " << ((double)(clock() - tStart)/CLOCKS_PER_SEC) << std::endl;
        float sum = 0;
        for ( int i = 0; i != 10; ++i )
            sum += myMap[ last ]; // search it
        std::cout << "Sum is " << sum << std::endl;
    }
    std::cout << "Time taken by map: " << ((double)(clock() - tStart)/CLOCKS_PER_SEC) << std::endl;
    tStart = clock();
    {
        std::vector< std::pair<float,int> > myVect;
        std::pair<float,int> middle;
        std::pair<float,int> last;
        for ( int i = 0; i != 10000000; ++i )
        {
            last = std::make_pair( ((float)std::rand()) / RAND_MAX, i );
            myVect.push_back( last );
            if ( i == 5000000 )
                middle = last; // element we will later search
        }
        std::sort( myVect.begin(), myVect.end() );
        std::cout << "Vector created after " << ((double)(clock() - tStart)/CLOCKS_PER_SEC) << std::endl;
        float sum = 0;
        for ( int i = 0; i != 10; ++i )
            sum += (std::find( myVect.begin(), myVect.end(), last ))->second; // search it
        std::cout << "Sum is " << sum << std::endl;
    }
    std::cout << "Time taken by vect: " << ((double)(clock() - tStart)/CLOCKS_PER_SEC) << std::endl;
    return 0;
}

g++ main.cpp -O3 -o main编译并得到:

Map created after 19.5357
Sum is 1e+08
Time taken by map: 21.41
Vector created after 7.96388
Sum is 1e+08
Time taken by vect: 8.31741

使用vector甚至搜索速度显然更快(使用 map 进行 10 次搜索几乎需要 2 秒,而使用 vector 只花了半秒钟(....

所以:

  • 我错过了什么吗?
  • 我的测试不正确/不准确吗?
  • map只是要避免的课程,还是真的存在map提供良好表现的情况?

通常,当您在查找中穿插大量插入和删除时,map会更好。如果您构建一次数据结构,然后只执行查找,则排序vector几乎肯定会更快,即使只是因为处理器缓存效应。由于向量中任意位置的插入和删除是 O(n( 而不是 O(log n(,因此这些将成为限制因素。

std::find具有线性时间复杂度,而map搜索具有log N复杂度。

当您发现一种算法比另一种算法快 100000 倍时,您应该怀疑!您的基准无效。

您需要比较现实的变体。可能,您的意思是将地图与二叉搜索进行比较。运行每个变体至少 1 秒的 CPU 时间,以便您可以实际比较结果。

当基准测试返回"0.00001 秒"所花费的时间时,您就处于时钟不准确的噪声中。这个数字没有任何意义。