Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在不使用if的情况下插入/更新std::无序_映射元素的最快方法是什么?_C++_Performance_Unordered Map - Fatal编程技术网

C++ 在不使用if的情况下插入/更新std::无序_映射元素的最快方法是什么?

C++ 在不使用if的情况下插入/更新std::无序_映射元素的最快方法是什么?,c++,performance,unordered-map,C++,Performance,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)); } auto it =

我目前有很多代码如下所示:

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));
}
auto it = my_dict.find(key);
if( it != my_dict.end() ) {
    it->second = value;
}
else {
    my_dict.insert(std::make_pair(key,value));
}
std::无序映射我的目录;
.
.
.
//如果字典中确实存在该键
如果(我的数字计数(键)=1){
my_dict[键]=值;
}
//如果是新钥匙
否则{
我的dict.insert(std::make_pair(key,value));
}

是否有任何方法可以通过每次覆盖该值来加快速度?

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

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));
}
auto it = my_dict.find(key);
if( it != my_dict.end() ) {
    it->second = value;
}
else {
    my_dict.insert(std::make_pair(key,value));
}
这样,如果
已经存在,并且您只有一次查找,您就不会修改
无序映射的结构


如果您不需要/访问
之后,另一个选项:

my_dict[key] = std::move(value);
如果
值的赋值非常昂贵,并且得益于移动语义,那么这可能会更好。

您只需这样做(对于
映射和
无序映射


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

std::unordered_map::insert_or_assign()

通常,您可以通过定义一个函数避免再次键入相同的内容来避免额外的键入。 如果您无权访问C++17的
insert\u或\u assign()
,您可以自己实现类似的功能:

bool InsertOrAssign(std::unordered_map& m, int key, int value) {
  // Your code or one of the suggested answers goes here
}

所有地图功能都执行搜索,因此无论是否存在键,都会搜索地图两次。您可以利用
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;
}

看来你应该用map@billz我想要O(1)的插入时间?我不想要一个日志树,[]会这样做。当然,复杂性必须是线性的。如果您想要更少的插入时间,请使用map
my_dict[key]=value
是您所需要的全部,如果需要则不需要。@user997112使用
(*my_dict_ptr)[key]
my_dict_ptr->operator[](key)
。@us2012大多数情况下,但在插入情况下,它首先插入一个默认构造值,然后分配它。以上避免了这种开销。在我走这条路线之前,我会认真地衡量一下简单的情况(
foo[key]=value;
)。如果没有显示这是一个问题的概要文件运行,请使用可读性更强的代码。当这个问题没有“性能”标签时,这就是我的答案:)我的一般经验是,大多数人误解了哪些东西会拖累他们的性能。在
无序的
映射中,
值类型
,我希望OP的代码与这两种解决方案之间的性能差异非常小。任何开销都很可能被优化掉。如果且仅当
值的默认构造非常昂贵时,使用
if-else
会更快。不过,在大多数情况下,
操作符[]
会执行此任务。使用gcc时,insert\u或\u assign()的速度可能较慢。看见