开发者

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

开发者 https://www.devze.com 2023-02-12 18:51 出处:网络
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开发者_JS百科 faster than the other? (supposing that the request
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开发者_JS百科 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).


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


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消