對Visual Studio C++ hash_map嚴謹一點的測試–轉載

來源:互聯網
上載者:User

在上次測試完成後,有一個網友mm304321141 (明兒)在留言上對測試資料進行了質疑,先謝謝他的指正。 我的確不知道Visual Studio C++ 預設的Dinkumware STL hash_map的hash_compase有兩個參數bucket_size 和min_buckets ,我自己實現的時候類是從stdext::hash_compare繼承的,忽視了這兩個參數,而上次測試的時候更是使用了預設範本參數。

玩benchmark測試的人,最怕人說不嚴謹,雖然我私人的測試環境很難服眾,但這次的測試也盡量認真一點。

測試環境:私人的機器,Genuine,1.6G雙核  2G記憶體

測試的編譯器:MSVC 2005,(上次用的2003)

測試代碼如下:

#include <stdio.h>

#include <conio.h>

 

#include <iostream>

#include <map>

#include <hash_map>

#include <algorithm>

 

#include <ace/OS.h>

#include <ace/Time_Value.h>

 

const size_t TEST_NUMBER         = 200000;

const size_t INIT_BUCKETS_NUMBER = 262144;

 

class test_hash_compare

{

 

public:

   //注意這個地方,我重新定義了這2個參數,【注意】

   static const size_t bucket_size = 4;

   static const size_t min_buckets = INIT_BUCKETS_NUMBER;

   //static const size_t min_buckets = 8;

   test_hash_compare()

   {

   }

   size_t operator( )( const size_t& Key ) const

   {

       return Key;

   }

 

   bool operator( )(

      const size_t& _Key1,

      const size_t& _Key2

   ) const

   {

       return (_Key1<_Key2)?true:false;

   }

};

 

void test_hash_map()

{

 

    ACE_Time_Value tvStart(0);

    ACE_Time_Value tvEnd(0);

    ACE_Time_Value tvPassTime(0);

 

tvStart = ACE_OS::gettimeofday();

 

    //這是使用STLPORT後才有的宏

#if defined _STLPORT_VERSION

    std::hash_map<size_t,int>   int_hash_map;

    //注意這行代碼,VS.NET預設的STL沒有這個函數的,而STLPort的實現有這個函數

    int_hash_map.resize(INIT_BUCKETS_NUMBER);

#else

    stdext::hash_map<size_t,int,test_hash_compare>   int_hash_map;

#endif //

 

    //測試20萬次

    //順序插入一組資料

    for (size_t i= 0;i<TEST_NUMBER;++i)

    {

        int_hash_map[i]=0;

    }

 

    //查詢40萬次,一半能查詢到,一半不能查詢到

    for (size_t i= 0;i<2*TEST_NUMBER;++i)

    {

        int_hash_map.find(i);

    }

 

    //得到毫秒的時間差

 

    tvEnd = ACE_OS::gettimeofday();

    tvPassTime = tvEnd - tvStart;

 

    std::cout<<"test_hash_map gettimeofday :"<<tvPassTime.msec()<<" "<<std::endl;

};

 

 

int main(int argc, char* argv[])

{

    for (int j=0;j<5;++j)

    {

        test_hash_map();

    }

    _getch();

    return 0;

}

上次使用debug版本一方面是為了拍麻煩,另一方面覺得自己的代碼簡單,擔心某些最佳化導致結果的不公。這次我採用了Release 版本進行比較,最後測試結果如下:

                                                                                                                                  表1 對hash_map在幾種環境下進行測試

測試方式
 STLPort版本的hash_map不使用resize函數

(耗時ms)
 STLPort版本的hash_map測試前使用resize函數

(耗時ms)
 微軟MSVC2005預設STL的hash_map,使用自訂的hash_compare函數
 微軟MSVC2005預設STL的hash_map,使用預設的hash_compare函數
 
 

 

 

【注意】我是按照我對MSDN裡面對bucket_size,min_buckets的說明進行的定義,我對bucket_size也進行了一些調整,沒有發現有什麼特別的最佳化空間,如果調整的更大,反而會影響降低速度。

【注意】為什麼第一次會快很多,我有點疑惑,先以為是感染資料,但是多次測試發現實際第一次的確要快不少,有點懷疑是頁面交換錯誤導致的。

【注意】使用debug版本測試的時候發現每次函數執行的事件並算特別長,但是我的等待事件卻出人意料的久遠,稍稍看了測試代碼,估計是MSVC的DEBUG版本的記憶體檢查導致的問題。

 

測試的結果,MSVC的結果並沒有更加爭氣,稍稍考慮一下,我的測試的確比較偏向STLPort,它的小對象分配器在我的測試中間可能大佔便宜。當然這也是STLPort(SGI STL)設計的好的地方。

最後說一句,對於MSVC的這個實現,我仍然報以無奈,或者說其不上流,即使在hash_compare中間最佳化bucket_size,min_buckets,可以提高速度。但如果要依靠這樣的方式初始化,對於很多實現開發人員要重新實現hash_compare才能得以實現效能最優。

還是那個老建議,如果可能,可以考慮使用STLPort的實現,當然這樣你可能要付出很多代價,(幾乎要重新編譯所有的庫)

 最後仍然對mm304321141 (明兒)表示感謝!

 

【本文作者是fullsail(雁渡寒潭),本著自由的精神,你可以在無盈利的情況完整轉載此文檔,轉載時請附上BLOG連結:http://blog.csdn.net/fullsail,否則每字一元不講價。】

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/fullsail/archive/2009/12/21/5045355.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.