Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding multiple lookups in map/unordered_map

Let's say we have an expensive function mapping string to int and want to cache results in a map.

The simplest code would be

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

But this has 2 lookups.

I therefore tend to write this

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

This has only one lookup, but seems a little clumsy. Is there a better way?

like image 332
Felix Dombek Avatar asked Nov 01 '25 17:11

Felix Dombek


1 Answers

Just use std::map::emplace() method:

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;
}
like image 172
Slava Avatar answered Nov 04 '25 08:11

Slava