我正在比较我写的一个简单的哈希函数,它只是将它乘以素数mod另一个素数(表大小),结果证明stl慢了100倍。这是我写的测试方法:
stdext:: hash_map<string, int> hashDict;
for (int l = 0; l < size; ++l){
hashDict[arr[l]] = l;
}
long int before3 = GetTickCount();
int c = 0;
while (c < size){
hashDict[arr[c]];
c++;
}
long int after3 = GetTickCount();
cout << "for stl class, the time is " << (after3 - before3) / 1000.0 << '\n';
cout << "the average is " << ((after3 - before3) / 1000.0 ) /long (size) << '\n';
字典的大小约为200k个元素,我写的散列函数的表大小有3m个条目,所以也许它与stl类的表大小非常小有关。有谁知道stl函数的表格大小是什么以及碰撞率.etc?
答案 0 :(得分:2)
VS2008 STL实现对字符串使用以下哈希函数:
size_t _Val = 2166136261U;
while(_Begin != _End)
_Val = 16777619U * _Val ^ (size_t)*_Begin++;
这并不比你的效率低,当然也不是100倍,我怀疑Builder版本有很大不同。不同之处在于测量(GetTickCount()
不是非常精确)或在计算哈希值以外的操作中。
我不了解C ++ Builder,但是一些STL实现在调试版本中内置了许多额外的检查和断言。您是否尝试过分析优化的发布版本?
如果您发布一个最小但完整的示例,我们可以帮助您弄清楚发生了什么,但没有更多的代码,真的没什么好说的。
答案 1 :(得分:0)
发布此答案:我认为你的错误价值。您实际上并没有使用散列值,只是引用它们,因此编译器可能会优化对哈希表的访问而不是hash_map
。
除了在极端和罕见的情况下,你仍然不会通过一个大的积分因子击败专业实现,同时仍然使用相同的算法,你是。你至少有可能赢得彩票中的大奖,而不是100倍。
更改测试代码以使用值。总结它们并打印出总和。这很快并迫使程序查找每个值。
答案 2 :(得分:0)
我可以确认调试版本和发布版本之间可能存在巨大差异。 在我的例子中,我有使用hash_map和list的程序。 调试版本运行超过8分钟。 发布版本在不到一秒的时间内运行。 这至少是480倍的时间差异。