47

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

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));
}

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

4

5 回答 5

71

你只需做 (for mapand unordered_map)

mydict[key]=value;
于 2013-10-05T12:35:59.757 回答
24

我认为它可能是这样最快的:

auto it = my_dict.find(key);
if( it != my_dict.end() ) {
    it->second = value;
}
else {
    my_dict.insert(std::make_pair(key,value));
}

这样你就不会修改unordered_mapifkey已经存在的结构并且你只有一个查找。


如果您以后不需要/访问,另一种选择value

my_dict[key] = std::move(value);

value在分配昂贵且受益于移动语义的情况下,这可能会更好。

于 2013-10-05T12:32:53.753 回答
8

要更新 C++17,您可以使用:

std::unordered_map::insert_or_assign()

http://en.cppreference.com/w/cpp/container/unordered_map/insert_or_assign

于 2018-04-18T16:05:31.500 回答
1

通常,您可以通过定义一个函数来避免额外的输入,从而避免您再次输入相同的内容。如果您无法访问 C++17's insert_or_assign(),您可以自己实现类似的东西:

bool InsertOrAssign(std::unordered_map& m, int key, int value) {
  // Your code or one of the suggested answers goes here
}
于 2018-04-18T16:20:52.137 回答
1

您的所有地图功能都执行搜索,因此无论是否存在密钥,您总是搜索地图两次。您可以利用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, emplaceand可以在不同情况下operator[]执行附加构造:并在插入发生之前执行此操作,并且在 key 不存在时默认构造映射值。因此,它们对于构造/复制/移动成本高昂(、非常大...)的类型并不理想。在这种情况下,改为使用(C++17)更合适:value_typeinsertemplaceoperator[]std::threadstd::arraytry_emplace

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
}
于 2020-07-29T12:35:19.463 回答