C++ hash_map find() 与 contains() 性能

C++ hash_map find() vs contains() performance

提问人:Philip Z. 提问时间:10/11/2023 最后编辑:EvgPhilip Z. 更新时间:10/11/2023 访问量:154

问:

如果我想检查某个元素是否包含在映射中并在之后直接使用它,那么在性能方面,更好的选择是什么?

std::unordered_map<int, std::string> my_map;
int my_key;

选项 1:

if (const auto& iter = my_map.find(my_key); iter != my_map.end()) {
      const auto& value = iter->second;
}

选项 2:

if (my_map.contains(my_key)) {
      const auto& value = my_map.at(my_key);
}

为了可读性,我更喜欢选项 2。但是,根据我的理解,选项 2 应该更慢,因为有两个哈希图查找。

C++ 性能 哈希图 标准

评论

0赞 chrysante 10/11/2023
没问题。不幸的是,C++ 中哈希表上的接口并不是最好的。
3赞 Yksisarvinen 10/11/2023
@273K 例外真的会被优化掉吗?如果不是,这可能比第二个选项的双树遍历差几个数量级。
7赞 Evg 10/11/2023
@273K 对我来说,这看起来像是滥用异常作为控制流,这很糟糕。
2赞 273K 10/11/2023
@Yksisarvinen 这取决于它多久提出一次。
1赞 user4581301 10/11/2023
如有疑问,请进行基准测试。请注意,对挑剔的东西进行基准测试是很困难的,但是如果你积累了像这样应该很容易的基准测试的经验,那么当你接触到挑剔的东西时,你会处于更好的状态。

答:

3赞 Ryley 10/11/2023 #1

你是对的。

使用效率更高,因为只执行一个查找,而第二个使用选项效率较低,因为您还必须执行查找。findcontainsat

评论

4赞 Evg 10/11/2023
编译器可能会使用 contains 和 at 进行优化,就像 just find 一样 - 看到这样的优化我会很惊讶。
0赞 Ryley 10/11/2023
@Evg 如果所说的不准确,对不起。我的意思是更像是“优化后,两者的性能大致相同”,这公平地说,不是吗?
3赞 chrysante 10/11/2023
@ryley 不,可能不是。如果任何 C++ 编译器将搜索逐一折叠成一个,我会感到惊讶。这意味着,在编译器变得更智能之前,非平凡的查找将发生两次,并且该版本的速度应该大约是原来的两倍。containsat
0赞 Ryley 10/11/2023
@Evg好的,谢谢你纠正我,我已经从我的回答中删除了错误信息。
1赞 Jérôme Richard 10/11/2023
这里是生成的代码,只是为了证明生成的代码是坏的(一次可以看到 + 是用 . s 很慢。但是,哈希映射通常很慢,因为它们很大时会因为缓存未命中而变慢,因此在这种情况下,哈希映射的开销可能不会那么大。不过,最好尽可能避免它。AFAIK,这就是为什么以前不可用的原因:这是关于性能的反模式。containsdivshroption2divdivcontains