在 STL 关联容器中使用基于迭代器的搜索和使用是否更快?

Ste*_*uer 6 c++ c++17 c++20

假设我正在尝试检查关联容器中是否存在某个项目,如果存在则对其进行处理。这样做的简单方法如下:

std::unordered_map<std::string, Whatever> thisIsAMap;

// C++17
if (thisIsAMap.count("key") > 0u) { doThing(thisIsAMap["key"]); }
// C++20
if (thisIsAMap.contains("key")) { doThing(thisIsAMap["key"]); }
Run Code Online (Sandbox Code Playgroud)

然而,这对我来说似乎总是有些浪费,因为它涉及两次查找相同的项目,这可能是一项非常昂贵的操作。相反,我倾向于这样做:

auto found = thisIsAMap.find("key");
if (found != thisIsAMap.end()) { doThing(found->second); }
Run Code Online (Sandbox Code Playgroud)

这只需要找到该项目一次,然后使用它。

后一种方法实际上更好吗?使用任何一种方法而不是另一种方法有什么好的理由吗?

Bar*_*rry 18

后一种方法实际上更好吗?

是的。有几个原因。

首先,做一次map查找肯定至少和做两次map查找一样快。最好的情况是,编译器优化了第二次查找,但我在实践中从未真正见过这种情况发生,而且这似乎很依赖。

其次,使用find意味着您只需键入"key"一次,而不是两次,这只会减少潜在的错误来源。

第三, using[]要求值类型是默认可构造的 - 所以除了性能和软件工程方面的原因更糟糕之外,它还可以为您的类型添加更多您可能无法满足的要求。

第四,从代码阅读的角度来看,更明显的是,您正在查找一个项目,然后在找到时使用该项目……而不是查找一个项目并再次查找相同的项目。