在不使用 if 的情况下插入/更新 std::unordered_map 元素的最快方法是什么?

新手上路,请多包涵

我目前有很多看起来像这样的代码:

 std::unordered_map<int,int> my_dict;
.
.
.
// If the key does exist in the dictionary
if(my_dict.count(key) == 1){
    my_dict[key] = value;
}

// If its a new key
else{
    my_dict.insert(std::make_pair(key,value));
}

有什么方法可以通过每次覆盖值来加快速度吗?

原文由 user997112 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 526
2 个回答

您只需这样做(对于 mapunordered_map

 mydict[key]=value;

原文由 Joe 发布,翻译遵循 CC BY-SA 3.0 许可协议

您的所有地图功能都执行搜索,因此无论是否存在密钥,您总是搜索地图两次。您可以利用 insert 检索插入是否发生(键不存在)或不(键存在)的事实并采取相应的行动:

 std::unordered_map<int,int> mydict;
bool inserted = false;
auto position = mydict.end();
std::tie(position, inserted) = mydict.insert({key, value});
if (inserted) {
  pos->second = value;
}

这相当于 mydict[key] = value ,因为无论如何我们都在分配新值。对于默认构造便宜的类型,我会选择 operator[] 相反,如果这是您唯一需要对地图做的事情。

All insert , emplace and operator[] can perform an additional construction of value_type in different situations: insert and emplace 在插入发生之前执行此操作,并且 operator[] 默认在 key 不存在时构造映射值。因此,它们不适合构建/复制/移动成本高昂的类型( std::thread ,非常大的 std::array …)。在这种情况下,使用 try_emplace 代替(C++17)更合适:

 std::unordered_map<int, expensive_type> mydict;
bool inserted = false;
auto position = mydict.end();
std::tie(position, inserted) = mydict.try_emplace(key, expensive_constructor_args);
if (!inserted) {
  // no expensive_type has been constructed
  // pos->second references the existing value
}

原文由 Jorge Bellon 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题