我实现了一个搜索缓存结果,它包含State类型的键(一个7个短整数的类)和一个类型为Socre的类(一个3个双精度类。)使用unordered_map至少比map慢20倍。为什么呢?
编辑:Darn it!我的哈希函数是
namespace std {
size_t hash<State>::operator()(State const& s) const {
size_t retval = hash<short>()(s.s[0]);
for (int i = 1; i < R; i += 2) { // 1 3 5
int x = (static_cast<int>(s.s[i + 1]) << 16)
+ (static_cast<int>(s.s[i]));
hash_combine(retval, x);
}
}
}
我忘了return retval
,所以它全都在碰撞!我希望unordered_map有一个hash_function_quality()函数来报告平均冲突次数。
答案 0 :(得分:16)
unordered_map的速度与散列函数的速度成正比。这绝不是一种直接的关系。例如,如果您使用最简单的散列函数:
std::size_t myHash(MyObjectType _object){ return 1; }
那么你最终得到的是一个集合,其行为类似于列表而不是散列容器。所有项目都将映射到一个存储桶,您必须遍历整个存储桶,直到找到所需的项目(可能需要O(N)时间。)
你需要做的是看两件事:
其中任何一个都可以并且会杀死性能。
答案 1 :(得分:9)
std::unordered_map
通常对于少量元素来说很慢。它需要一段固定的(非常)时间,但可能还需要相当长的时间。
std::map
比std::unordered_map
更简单。访问元素所花费的时间取决于元素的数量,但随着元素数量的增加越来越少。与c
相比,std :: map的大哦因子std::unordered_map
通常也非常小。
一般情况下,除非您有特定原因要使用std::map
,否则最好使用std::unordered_map
而不是std::unordered_map
。如果您没有大量元素,这尤其适用。
答案 2 :(得分:8)
unordered_map
使用哈希表,因此哈希表现不佳的最明显原因是因为你有太多的冲突。您可以考虑使用不同的非默认哈希函数,它可以为您的键类型提供更好的结果。
答案 3 :(得分:0)
有关
我希望unordered_map有一个 hash_function_quality()函数 报告平均数 碰撞。
我认为以下功能可能会有所帮助。
unordered_map::load_factor
float load_factor() const;
The member function returns the average number of elements per bucket.
降低load_factor
,散列函数更好。