测试方法:加载文件,将数据分别插入到std::map和boost::unordered_map中,分别保存string作为key和int作为key的map数据,计算插入时间,根据列表分别在对应的map中查找一次所有的key值,计算查找耗时:
测试结果:插入耗时boost::unordered_map是std map的一半左右,查找耗时是std map的1/3左右
测试代码:
#include <boost/unordered/unordered_map.hpp>
#include <map>
#include <iostream>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <sstream>
#include <fstream>
#include <sys/time.h>
using namespace std;
void ParseDataList(const string &typelist, vector<string> &vecList)
{
vecList.clear();
if (typelist.length() == 0)
return;
const char split = ',';
const char* pBegin = typelist.c_str();
if (pBegin == NULL)
return;
const char* pEnd = pBegin;
while (*pEnd != '\0')
{
bool bFH = false;
if (*pEnd == '"')//csv文件里,如果字段里含有,的,整个字段会加""
{
bFH = true;
pEnd++;
pBegin++;
}
char cTemp[2048] = { 0 };
if (bFH)
{
while (*pEnd != '"' && *pEnd != '\0') pEnd++;
}
else
{
while (*pEnd != split && *pEnd != '\0') pEnd++;
}
if (*pEnd == '\0')
{
strncpy(cTemp, pBegin, pEnd - pBegin);
vecList.push_back(cTemp);
break;
}
strncpy(cTemp, pBegin, pEnd - pBegin);
vecList.push_back(cTemp);
pEnd++;
if (bFH) pEnd++;
pBegin = pEnd;
}
}
map<string, unsigned long long> mapStockToInner;
boost::unordered_map<string, unsigned long long> unmapStockToInner;
map<unsigned long long, string> mapInnerToString;
boost::unordered_map<unsigned long long, string> unmapInnerToString;
vector<string> vecCodeList;
vector<unsigned long long> vecInnerList;
static string MakeCodeKey(unsigned short nMarket, const char* code)
{
stringstream ss;
ss << nMarket;
ss << code;
return ss.str();
}
long long Time2Int()
{
struct timeval timeNow;
gettimeofday(&timeNow, NULL);
long long iTime = (((long)timeNow.tv_sec) * 1000 * 1000 + (long)timeNow.tv_usec);
return iTime;
}
template<typename TKEY, typename TValue, typename TMap>
unsigned long long InnserToMap(TKEY &key, TValue &value, TMap &tmap)
{
long long timeStart = Time2Int();
tmap[key] = value;
long long timeEnd = Time2Int();
return timeEnd - timeStart;
}
bool Load(const char* file)
{
ifstream ifs(file);
if (!ifs.is_open())
{
cout << "open file failed." << file << endl;
return false;
}
string line;
unsigned long long mapkeytime = 0;
unsigned long long mapinnertime = 0;
unsigned long long unmapkeytime = 0;
unsigned long long unmapinnertime = 0;
while (getline(ifs, line))
{
vector<string> vecTemp;
ParseDataList(line, vecTemp);
short nMarket = atoi(vecTemp[1].c_str());
string code = vecTemp[2];
unsigned long long incode = atoll(vecTemp[3].c_str());
string key = MakeCodeKey(nMarket, code.c_str());
mapkeytime += InnserToMap(key, incode, mapStockToInner);
unmapkeytime += InnserToMap(key, incode, unmapStockToInner);
mapinnertime += InnserToMap(incode, key, mapInnerToString);
unmapinnertime += InnserToMap(incode, key, unmapInnerToString);
vecCodeList.push_back(key);
vecInnerList.push_back(incode);
}
ifs.close();
cout << "std map string insert time:" << mapkeytime
<< ",std map int insert time:" << mapinnertime
<< ",un map string insert time:" << unmapkeytime
<< ",un map int insert time:" << unmapinnertime
<< endl;
return true;
}
template<typename vecT, typename mapT>
void TestMap(vecT& vt, mapT &mt, const char* name)
{
long long timeStart = Time2Int();
for (size_t i = 0; i < vt.size(); ++i)
{
typename mapT::iterator it = mt.find(vt[i]);
if (it == mt.end())
{
cout << "not find key " << vt[i] << endl;
}
}
long long timeEnd = Time2Int();
cout << name<<"find time=" << timeEnd - timeStart<<endl;
}
void Test()
{
//test std map key->code
TestMap(vecInnerList, mapInnerToString, "std map innercode->key ");
//test boost unorder map key->code
TestMap(vecInnerList, unmapInnerToString, "boost unorderedmap innercode->key ");
//test std map code->key
TestMap(vecCodeList, mapStockToInner, "std map key->innercode ");
//test std map code->key
TestMap(vecCodeList, unmapStockToInner, "boost unorderedmap key->innercode ");
}
int main()
{
if (Load("dict.txt") == false)
{
cout << "load file failed." << endl;
return -1;
}
Test();
}