在上次測試完成後,有一個網友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