与 std::unordered_map 或 std::map 相比,MFC CMap 是否具有良好的性能?
Does MFC CMap have a good performance compared to std::unordered_map or std::map
MFCCMap
和std::unordered_map
或者std::map
相比性能好吗,我问这个问题是因为我公司要开项目,加速开发 我将从现有的 "similar" 项目开始,但在最后一个项目中,有 MFC CMap
(散列 table 映射)我认为使用 std::unordered_map
可以也许提高性能。我没有在互联网上找到与 CMap
相关的任何基准测试或好文章。
否则,对于 std::unordered_map
,我是否必须像 CMap
一样为散列 table 修复大小以避免冲突和性能问题?
好的 20 秒搜索 "MFC CMap" 找到
Lookup uses a hashing algorithm to quickly find the map element with a
key that exactly matches the given key.
所以 big-O 效率会像 unordered_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;
以下是 1000000 个元素 在 Intel Core i5 2.5Ghz 8GB RAM (Lenovo 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
并没有那么糟糕!
MFCCMap
和std::unordered_map
或者std::map
相比性能好吗,我问这个问题是因为我公司要开项目,加速开发 我将从现有的 "similar" 项目开始,但在最后一个项目中,有 MFC CMap
(散列 table 映射)我认为使用 std::unordered_map
可以也许提高性能。我没有在互联网上找到与 CMap
相关的任何基准测试或好文章。
否则,对于 std::unordered_map
,我是否必须像 CMap
一样为散列 table 修复大小以避免冲突和性能问题?
好的 20 秒搜索 "MFC CMap" 找到
Lookup uses a hashing algorithm to quickly find the map element with a key that exactly matches the given key.
所以 big-O 效率会像 unordered_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;
以下是 1000000 个元素 在 Intel Core i5 2.5Ghz 8GB RAM (Lenovo 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
并没有那么糟糕!