簡體   English   中英

我的哪種情況會std :: map <A,B> 比排序的std :: vector更快 <std::pair<A,B> &gt;?

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

我在一些代碼中使用map來存儲有序數據。 我發現對於巨大的地圖,破壞可能需要一段時間。 在這個代碼我有,用vector<pair>替換map減少處理時間10000 ...

最后,我很驚訝我決定將map表現與排序的vectorpair進行比較。

我很驚訝,因為我無法找到的情況下map比一個快排序vectorpair (隨機填充后排序)......必須有某些情況下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秒”時間時,您可以很好地處理時鍾誤差。 這個數字什么都沒有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM