在我的程序中,CMap
的大小乘以1.2 IIRC 6230,这比我用InitHashTable
(即6203)的大小要好。
我把另一个InitHashTable
值作为素数:9973
这是正确的吗?或者我应该选择更接近素数到6203.或者我可以选择更大的素数?
答案 0 :(得分:1)
这是使用VS2015的CMap
的测试结果。它建议使用素数不会产生很大的差异,初始化是否比预期值多20%或更少并不重要。
无论是否有素数或初始化都没有错误。我认为CMap
文档中对“碰撞”的引用与性能有关。
对于较大的数据集,您只需使用预期的数据大小即可。例如,如果预期大小为6,000,那么只需使用map.InitHashTable(6000)
。默认值为17,较低的值会降低性能。
还有std::map
的测试结果,它不需要初始化并且非常快。
void test()
{
CString msg;
//build test vector
int size = 100000;
std::vector<CString> vs;
for (int i = 0; i < size; i++)
{
CString s;
s.Format(L"str%d", i);
vs.push_back(s);
}
{//using prime number, 20% larger than expected size
int t = GetTickCount();
int init_size = 120011;
CMap<LPCTSTR, LPCTSTR, int, int> map;
map.InitHashTable(init_size);
for (int i = 0; i < size; i++)
map[vs[i]] = i;
msg.AppendFormat(L"CMap Initialized: %d, time:%d\n", init_size, GetTickCount() - t);
}
{//using non-prime number and 20% less than expected size
int t = GetTickCount();
int init_size = 80000;
CMap<LPCTSTR, LPCTSTR, int, int> map;
map.InitHashTable(init_size);
for (int i = 0; i < size; i++)
map[vs[i]] = i;
msg.AppendFormat(L"CMap Initialized: %d, time:%d\n", init_size, GetTickCount() - t);
}
{//using non-prime number and default initialization (m_nHashTableSize=17)
int t = GetTickCount();
CMap<LPCTSTR, LPCTSTR, int, int> map;
for (int i = 0; i < size; i++)
map[vs[i]] = i;
msg.AppendFormat(L"CMap Initialized: %d, time:%d\n", 17, GetTickCount() - t);
}
{//std::map test
int t = GetTickCount();
std::map<CString, int> mp;
for (int i = 0; i < size; i++)
mp[vs[i]] = i;
msg.AppendFormat(L"std::map time:%d\n", GetTickCount() - t);
}
//error test:
int init_size = 1000; //only a fraction of expected size!
CMap<LPCTSTR, LPCTSTR, int, int> map;
map.InitHashTable(init_size);
for (int i = 0; i < size; i++)
map[vs[i]] = i;
for (int i = 0; i < size; i++)
{
if (map[vs[i]] != i)
{
AfxMessageBox(L"errorTest - fail");
return;
}
}
msg.AppendFormat(L"no error");
AfxMessageBox(msg);
}
测试结果:(具有优化功能的发布模式)
CMap Initialized: 120011, time:31
CMap Initialized: 80000, time:47
CMap Initialized: 17, time:5110
std::map time:78
no error
结果只是一个粗略的估计
答案 1 :(得分:0)
std::map
使用红黑树,CMap
实现为哈希表。所以这是两个完全不同的容器。根据MSDN的最佳性能,哈希表大小应该是素数。为了最大限度地减少冲突,大小应该比最大的预期数据集大约20%。