在什么情况下 std::unordered_map 的行为会很慢?
Under what circumstances will std::unordered_map behave very slow?
我做了一些随机测试,但我无法得出结论。
如果在映射和unordered_map中插入 1000000 个整数,则 map 使用的时间是 3 倍。
如果插入 1000000 个字符串,则 map 使用的时间是 2 倍。
在什么情况下 std::unordered_map 的行为会很慢?
提前谢谢。
UPD:: gcc 版本 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3).所有测试都没有 -O2。
法典:
答.cpp:std::map<int, int> M;
B.cpp:std::unordered_map<int, int> M;
g(i, 1, 1000000) {
M[i] = rand() % i;
}
我的测试结果:
yyhs@yyhs-Pro:~/Documents$ g++ a.cpp -o a -g --std=c++11 && time ./a
real 0m0.659s
user 0m0.653s
sys 0m0.004s
yyhs@yyhs-Pro:~/Documents$ g++ b.cpp -o b -g --std=c++11 && time ./b
real 0m0.260s
user 0m0.251s
sys 0m0.008s
yyhs@yyhs-Pro:~/Documents$ g++ a.cpp -o a -g --std=c++11 -O2 && time ./a
real 0m0.290s
user 0m0.282s
sys 0m0.008s
yyhs@yyhs-Pro:~/Documents$ g++ b.cpp -o b -g --std=c++11 -O2 && time ./b
real 0m0.081s
user 0m0.081s
sys 0m0.000s
我的问题是,什么情况可能导致std::unordered_map变慢。
像往常一样,这将取决于特定的实现,但这并不完全正确,标准保证std::unordered_map
将逐渐优于std::map
。 只有常数因素会因实施而异。std::map
的插入时间为O(log N),std::unordered_map
的平均插入时间为O(1)。 有关详细信息,请参见 n3690 中的 §23.4.4.1 和 §23.5.4。
一般来说,除非您发生大量碰撞,否则std::unordered_map
的表现将大大优于std::map
(如您所观察到的)。 您可以通过选择放置在同一存储桶中的密钥来创建冲突。 这需要了解哈希函数以及从哈希值到存储桶的映射,但如果攻击者可以控制哈希表中的键,则攻击者可以利用这些知识使您的程序变慢。 因此,在公开的应用程序中使用随机哈希函数是很常见的。
在病理情况下,如果你的哈希函数选择不当(评估速度非常慢或产生许多碰撞),std::map
的表现可能会优于std::unordered_map
。 这是非常不典型的。
作为次要说明,标准库std::unordered_map
倾向于是一个开放的哈希表,以满足C++标准在迭代器行为方面的要求。 众所周知,这对于许多应用程序来说远非最佳,并且有许多替代哈希表库的性能更好。
- 存储在 std::map/std::set 中,与在存储所有数据后对向量进行排序
- 如何在<N>不发生内存泄漏的情况下同时(线程安全)填充 c++11 std::map<std::string,std::bitset*>?
- 无法在 std::map<std::string,std::shared_ptr 中设置值<class>>
- 如何在C++中迭代集合映射(std::map<std::set< char>, int >)?
- 如何初始化结构字段 std::map<std::string, std::string>称为参数
- issue with std::map std::find
- 为什么 std::map< std::map >不释放内存?
- C++ map<std::string> vs map<char *> 性能(我知道,"again?" )
- 确定运行时std::map/std::set的内存使用情况
- 映射上的模板参数无效 std::map< std::string, Stock*> &Stock
- 我的SFINAE检查std::map/std::vector有什么问题
- 使用 std::map<std::string, int> 计算表达式树
- 将数据从两种不同的数据结构插入 std::map <std::string, int> mymap 并通过套接字发送
- 类中的编译器错误,数据类型为 typedef map<std::string,std::p air<std::string,vector<int>>> MapPai
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- 如何填写和访问 std::map<std::p air<enum1, enum2>, funcPtr>?
- 二进制'<':找不到 map<std::string shared_ptr 的运算符<Foo>>
- 如何将 2 个字符* 数组直接映射到 std::map<std::string,std::string>
- C++ std::map<std::string, int> 获取键以特定字符串开头的值
- 从取消引用的迭代器返回 std::map<std::string, int> 时出现巨大的内存泄漏