我如何更有效地插入到std :: map中

时间:2016-06-27 07:52:44

标签: c++ dictionary

我的代码类似于:

struct Record{
     std::string key;
     // ...
};

void push_record(Record &out, std::map<std::string, int> &vmap){
    const auto &it = vmap.find(out.key);

    long pos;

    if (it != vmap.end()){
        pos = it->second;
    }else{
        pos = calculate_pos(out);
        vmap.insert( Record(std::move(out.key), pos) ); // here move
    }

    // use pos
}

如何提高代码效率?

目前,代码效率不高,因为它会在地图中查找两次。首先是它检查值,第二次是在插入时。

我也想使用std::move(out.key),这就是为什么我没有使用像vmap[out.key]这样的东西。

我看到你可以将建议传递给insert,但我无法找到好的例子。

1 个答案:

答案 0 :(得分:1)

std::map有一个方法upper_bound,您可以使用该方法找到比当前元素更大的第一个元素:

const auto it = vmap.upper_bound(out.key);

由于map不能包含重复键,并且这是第一个更大的元素,因此具有给定键的值只能位于前一个迭代器位置,或者根本不在地图中:

// Begin iterator means it definitely isn't in map
if(vmap.empty() || it == vmap.begin()) {
    // Perform insert...
} else {
    if((--it)->first != out.key)) {
        // Doesn't exist, perform insert with hint.
        // Note it will be inserted just prior to this (C++11).
        vmap.insert(++it, ...);
    } else {
      // It's in the map, do stuff with it
    }
}

正如其他人所说,这可能是微观优化。这也使得代码更难以阅读,所以在使用这样的东西之前我会认真地建议分析。