避免在map/unordered_map中进行多次查找

Fel*_*bek 3 c++ performance dictionary stdmap

假设我们有一个昂贵的函数映射stringint并希望将结果缓存在地图中.

最简单的代码就是

int mapStringToIntWithCache(std::string const& s) {
    static std::unordered_map<std::string, int> cache;
    if (cache.count(s) > 0) return cache[s];
    else return cache[s] = myExpensiveFunction(s);
}
Run Code Online (Sandbox Code Playgroud)

但这有2次查找.

因此,我倾向于写这个

int mapStringToIntWithCache(std::string const& s) {
    static std::unordered_map<std::string, int> cache;
    size_t sizeBefore = cache.size();
    int& val = cache[s];
    if (cache.size() > sizeBefore) val = myExpensiveFunction(s);
    return val;
}
Run Code Online (Sandbox Code Playgroud)

这只有一个查找,但似乎有点笨拙.有没有更好的办法?

Sla*_*ica 7

只需使用std::map::emplace()方法:

int mapStringToIntWithCache(std::string const& s) {
    static std::unordered_map<std::string, int> cache;
    auto pair = cache.emplace( s, 0 );
    if( pair.second )
         pair.first->second = myExpensiveFunction(s);
    return pair.first->second;
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果C++ 17可用,您也可以使用`try_emplace`.哪个更好,因为`emplace`可以复制`s`字符串参数. (2认同)