在什么情况下std :: unordered_map表现得很慢?

时间:2016-06-23 02:32:32

标签: c++

我做了一些随机测试,但我无法得出结论。

如果将1000000个整数插入到地图和unordered_map中,则map使用的时间要大3倍。

如果插入1000000个字符串,那么map使用的时间要大2倍。

在什么情况下std :: unordered_map会表现得很慢?

提前致谢。

UPD :: gcc version 4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04.3)。所有测试都没有-O2。

代码:

a.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变慢。

1 个答案:

答案 0 :(得分:3)

与往常一样,这将取决于具体的实现,但这并非完全正确,标准保证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 ++标准关于迭代器行为的要求。众所周知,这对于许多应用程序而言并不是最优的,并且有许多替代哈希表库可以表现得更好。