Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::map: is find(key)->second faster than the [] operator?

Tags:

c++

map

stl

std::map<long, double> x;
x[5] = 1.2;

double y = x[5];
double z = x.find(5)->second;

Will one of these 2 assignments execute faster than the other? (supposing that the requested key is always present in the map) Is there any overhead associated with the dereferencing of the iterator when doing x.find(5)->second ?

EDIT: Thanks for the replies. In my particular function, now that I know it is not slower, I will probably go with x.find(5)->second as I need to mark my function const (the map is a member variable) and the [] operator obviously does not allow that (as it potentially modifies the map is a key is missing).

like image 951
Laurent Avatar asked Feb 20 '11 15:02

Laurent


People also ask

Is map faster than set?

The map solution results in "Time Limit Exceeded on Test 3", whereas the set solution results in "Time Limit Exceeded on Test 2", which means that Test 2 is such that the map solution works faster on it than the set solution.

What is the time complexity of the find () method of the std::map container?

The time complexity for searching elements in std::map is O(log n).

Does map order the key C++?

By default, a Map in C++ is sorted in increasing order based on its key.

Is std::map sorted by key?

std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare . Search, removal, and insertion operations have logarithmic complexity.


3 Answers

This doesn't answer your question, but I would point out some problem with the way you're using find.

double y = x[5];
double z = x.find(5)->second;

I cannot comment on which is faster. But I can surely say that the first approach is safe!

What if the map doesn't contain the given key?

In the first approach, it will create a new pair with the given key, and initialize the value with default value of double (which is zero), and return it.

But the second aproach? find will return map::end if the specified key is not found in the container, and you're dereferencing it. Program crash!

The correct way to use find is:

std::map<long, double>::iterator it;    
if ( (it = x.find(key)) != x.end() )
{
    double value = it->second;
}
like image 117
Nawaz Avatar answered Nov 05 '22 14:11

Nawaz


Took this straight from <map>:

mapped_type& operator[](const key_type& _Keyval)
    {   // find element matching _Keyval or insert with default mapped
    iterator _Where = this->lower_bound(_Keyval);
    if (_Where == this->end()
        || this->comp(_Keyval, this->_Key(_Where._Mynode())))
        _Where = this->insert(_Where,
            value_type(_Keyval, mapped_type()));
    return ((*_Where).second);
    }

iterator find(const key_type& _Keyval)
    {   // find an element in mutable sequence that matches _Keyval
    iterator _Where = lower_bound(_Keyval);
    return (_Where == end()
        || _DEBUG_LT_PRED(this->comp,
            _Keyval, _Key(_Where._Mynode()))
                ? end() : _Where);
    }

It looks about the same. Should there be any difference between:

iterator _Where = this->lower_bound(_Keyval);
return ((*_Where).second);

and

iterator i = x.find(5);
double d = (*i).second;

I wouldn't think so.

like image 42
Marlon Avatar answered Nov 05 '22 14:11

Marlon


The first assignment using operator[] will have to perform the same dereference to retrieve the value that is explicit in find()->second. You can profile to be sure but the performance should be close enough that you should use the form that is clearest in your code.

like image 25
Blastfurnace Avatar answered Nov 05 '22 13:11

Blastfurnace