vc的hash_map怎麼啦

以下比較均基於 release 版本,debug 有調試信息不能作爲標準。
#include "stdafx.h"
#include <iostream>
#include <string>
#include <map>
#include <hash_map>
#include <afxtempl.h>
#include <atlstr.h>
using namespace std;
#pragma warning(disable : 4996)

int _tmain(int argc, _TCHAR* argv[])
{
    srand((unsigned)time(0));
    char str[50];
    map<string,int> smap;
    map<string,int>::value_type val_type;
    hash_map<string,int> hmap;
    CMap<CString,LPCTSTR,int,int&> cmap(2221);


    for(int i=0;i<2048;i++)
    {
        int temp = rand();
        sprintf(str,"%d%d%",temp,temp);
        smap[str] = i;
        hmap[str] = i;
        cmap[str] = i;
    }

    map<string,int>::iterator it;
    for(it=smap.begin(),i=0;it!=smap.end()&&i<1000;it++,i++)
    {
        //cout<<it->first<<" "<<it->second<<endl;

    }
   
    LARGE_INTEGER c1,c2;
    QueryPerformanceCounter(&c1);
    smap.find(it->first);

    hash_map<string,int>::iterator it11;
    QueryPerformanceCounter(&c2);
    cout<<c2.QuadPart-c1.QuadPart<<endl;
    QueryPerformanceCounter(&c1);
    it11 = hmap.find(it->first);
    QueryPerformanceCounter(&c2);
    cout<<c2.QuadPart-c1.QuadPart<<endl;
    CString cs = it->first.c_str();
    QueryPerformanceCounter(&c1);
    cmap.Lookup(cs,i);
    QueryPerformanceCounter(&c2);
    cout<<c2.QuadPart-c1.QuadPart<<endl;
 
    cout<<it11->first<<" "<<it11->second<<endl;
   
    return 0;
}
對於sgi stl    map hash_map  和 mfc 的cmap 執行時間如下: 測試環境vc2003
map              5000-6000 左右
hash_map  3000-4550 左右
cmap            4000-11844 左右
但是當使用vc hash_map 的時候居然經常在20000 以上, 差距也太大了, 而且要聲明hash函數和比較函數也麻煩,要生成一個如下相似的類, 跟sgi stl 差異很大。
template<class _Kty,
class _Pr = less<_Kty> >
class hash_compare
{   
public:
    enum
    {   
        bucket_size = 8,   
        min_buckets = 16
    };   
    hash_compare()
            : comp()
    {  
    }
     hash_compare(_Pr _Pred)
            : comp(_Pred)
    {    // construct with _Pred comparator
     }
     size_t operator()(const _Kty& _Keyval) const
     {    // hash _Keyval to size_t value
            return ((size_t)hash_value(_Keyval));
     }
     bool operator()(const _Kty& _Keyval1, const _Kty& _Keyval2) const
     {    // test if _Keyval1 ordered before _Keyval2
            return (comp(_Keyval1, _Keyval2));
     }
protected:
    _Pr comp;
};
如果使用了較長字符串做key,數據量很大,不需要排序使用hash_map比map要有效率(hash 函數不能太差),上面的例子因爲生成的都是隨機數字,相對文本字符串比較次數要多一些,開頭只有1-9 9中情況,不像文本有26個字符,算上大小寫數字就更多了, 所以map本可以表現得更好一點.
不過如果是vc的話,最好還是移植sgi 的hash_map 或者用mfc的cmap . 而且在msdn中: 如果您在 std 命名空間中使用 <hash_map> 和 <hash_set> 頭文件的成員,將會顯示 C4996.在未來版本中可能不再支持此函數。

或許那裏用的不對,但如此基本操作不應該有成倍的差距

現在又到快速排序了,對於sort() 函數,sgi版本 稍快於普通快速排序,遠遠大於vc 自己身的快速排序(或許稱不上快速排序),有2倍多的差距阿. 看來開源就是好啊。sigh 還是裝個stlport , 跨平臺也省事。

最簡單的快速排序
int partation(int* a,int l,int r)
{
    int i=l-1,j=r,v=a[r];
    for(;;)
    {
          while(a[++i] < v);
          while(a[--j] > v) if(j<=i) break;
          if(j<=i) break;
          swap(a[i],a[j]);
    }
    swap(a[i],a[r]);
    return i;
}

void qsort(int* a,int l,int r)
{
    while(l<r)
    {
         // sig stl 爲了防止分割惡化, 相當於多了一段。所以速度略好於普通快排
         //  if(r-l<32)
         // {
         //       insertsort(a,l,r);
        //        return;
        //  }
        int i = partation(a,l,r);
         qsort(a,l,i-1);
          l = i+1;
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章