相比有很好的性能MFC CMap
与std::unordered_map
或std::map
相比有很好的性能,我问这个问题是因为我要在我的公司启动一个项目,并加速开发我要开始一个现有的“类似”项目,但在这最后,有MFC CMap
(哈希表地图)我认为使用std::unordered_map
可能会提高性能。我在互联网上没有找到任何与CMap
相关的基准或好文章。 否则,使用std::unordered_map
我是否还必须修复散列表的大小,如CMap
以避免冲突和性能问题?MFC CMap与std :: unordered_map或std :: map
回答
我做了很简单的性能对比测试:
int nElements = 1000000;
CMap<int, int, CString, LPCTSTR> MfcHashTable;
MfcHashTable.InitHashTable(nElements);
// CMap insert
DWORD dwStart = ::GetTickCount();
for(int i=0; i<nElements; i++)
{
CString sBase;
sBase.AppendFormat(_T("Test String %d"), i);
MfcHashTable[i] = sBase;
}
DWORD dwMfcMapInsert = ::GetTickCount() - dwStart;
// CMap lookup
CString sValue;
dwStart = ::GetTickCount();
for(int i=0; i<nElements; i++)
{
MfcHashTable.Lookup(i, sValue);
}
DWORD dwMfcMapLookup = ::GetTickCount() - dwStart;
// std::map insert
std::map<int, CString> StdMap;
dwStart = ::GetTickCount();
for(int i=0; i<nElements; i++)
{
CString sBase;
sBase.AppendFormat(_T("Test String %d"), i);
StdMap[i] = sBase;
}
DWORD dwStdMapInsert = ::GetTickCount() - dwStart;
//std::map lookup
dwStart = ::GetTickCount();
std::map<int, CString>::iterator it;
for(int i=0; i<nElements; i++)
{
it = StdMap.find(i);
CString sBase = it->second;
}
DWORD dwStdMapLookup = ::GetTickCount() - dwStart;
// std::unordered_map insert (hash table)
std::unordered_map<int, CString> StdUnordMap;
dwStart = ::GetTickCount();
for(int i=0; i<nElements; i++)
{
CString sBase;
sBase.AppendFormat(_T("Test String %d"), i);
StdUnordMap[i] = sBase;
}
DWORD dwStdUnordMapInsert = ::GetTickCount() - dwStart;
//std::map lookup
dwStart = ::GetTickCount();
std::unordered_map<int, CString>::iterator it1;
for(int i=0; i<nElements; i++)
{
it1 = StdUnordMap.find(i);
CString sBase = it1->second;
}
DWORD dwStdUnordMapLookup = ::GetTickCount() - dwStart;
cout << dwMfcMapInsert << endl;
cout << dwMfcMapLookup << endl;
cout << dwStdMapInsert << endl;
cout << dwStdMapLookup << endl;
cout << dwStdUnordMapInsert << endl;
cout << dwStdUnordMapLookup << endl;
下面是结果百万元上Intel酷睿i5 2.5Ghz的8GB内存(联想ThinkPad X230):
MFC CMap insert: 1125
MFC CMap lookup: 125
std::map insert: 1406
std::map lookup: 172
std::unordered_map insert: 1578
std::unordered_map lookup: 140
所以令人惊讶的是CMap
是这里的赢家。事实证明,丑陋的传统CMap
毕竟不是那么糟糕!
如果你包含破坏。 CMap甚至更快,因为它使用与池分配器相当的内存块。如果你仔细研究代码的构造,它会清楚地知道MFC Map是“更好的”。 ;)即使它过时了。 – xMRi
有趣的是,我也做了一个基准测试,我用一个大的txt字典文件和高性能的coutner来测量时间,但我做了一个错误,对于std :: unordered_map我使用了std :: string类型的值或键,而对于CMaps,我使用了CStrings,所以在这种情况下,unordered_map击败CMaps(几十毫秒),我将重写我的基准测试并为每个人提供CString(因为我无法将std :: string作为值在CMap中,我不记得它为什么不起作用) – Aminos
我认为测试是在'CMap'的青睐,因为大小是已知的('InitHashTable'),它会慢得多,如果规模很大,并且未知。同时'unordered_map'没有利用'reserve'。 'CMap'只查找速度更快。 –
好20秒搜索“MFC的CMap”发现
查找使用哈希算法来与 关键一个与给定键匹配快速查找地图元素。
因此,大O效率将会像unordered_map
。
可否请投票者解释?这个问题问CMap是否具有与'map'或'unordered_map'类似的性能。我回答说它会和'unordered_map'类似。为什么这是一个不好的答案? –
- 1. 使用MFC CMap(或std :: map)的帮助请
- 2. std :: tr1 :: unordered_map是否有与std :: map :: lower_bound类似的std :: algorithm?
- 3. STL的MFC等价std :: map
- 4. mem_set为std :: map或std :: list
- 5. std :: map插入或std :: map查找?
- 6. 帮助理解std :: map/boost :: unordered_map
- 7. C++ std :: unordered_map
- 8. Doxygen可以识别std :: shared_ptr或std :: map
- 9. std :: map
- 10. std :: unordered_map初始化
- 11. 呼叫到std :: unordered_map ::刀片()
- 12. 在std :: map中插入std :: map
- 13. std :: map初始化std :: vector
- 14. std :: map with std :: weak_ptr key
- 15. std :: tr1 :: unordered_map的C++相等
- 16. std :: unordered_map插入提示
- 17. 如何使用std :: bind与std :: function和std :: map
- 18. 使用std :: map与指针
- 19. std :: map与lambda比较器
- 20. const_cast问题与std :: map
- 21. C++,boost :: numeric :: ublas :: mapped_matrix - 使用std :: tr1 :: unordered_map代替std :: map时的迭代问题
- 22. C++的std :: unordered_map复杂
- 23. print unordered_map <std :: string,std :: list <std::string>
- 24. boost :: unordered_map缺少reserve()像std :: unordered_map
- 25. boost :: lambda std :: map
- 26. std :: map :: insert exception
- 27. Readonly std :: map?
- 28. HowTo sort std :: map?
- 29. std :: map performance C++
- 30. Luabind:return_stl_iterator for std :: map
***我没有在interne上找到与CMap相关的任何基准测试或好文章***为什么不用自己的数据集进行基准测试?您将在硬件上使用哪种数据集?在生产中使用? – drescherjm
CMap没有移动支持(如果您想从函数返回一个参数,您必须始终将其作为输出参数传递),并且不会在调试器中的监视窗口中显示任何有用内容。你还必须编写像'CMap map;'而不是'std :: unordered_map map;'的代码。如果我是你,我甚至不会考虑使用它 - 但这取决于你。 –
drescgerjm,我在过去做过(std :: map vs CMap),但我不相信......但如果我在这里没有得到答案,我会做另一个基准测试(CMaps vs unordered_map)。 – Aminos