Подтвердить что ты не робот

Std:: map: find (key) → секунд быстрее, чем оператор []?

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

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

Будет ли одно из этих двух назначений выполняться быстрее, чем другое? (предположим, что запрошенный ключ всегда присутствует на карте) Существуют ли какие-либо служебные данные, связанные с разыменованием итератора при выполнении x.find(5)->second?

EDIT: Спасибо за ответы. В моей конкретной функции теперь, когда я знаю, что это не медленнее, я, вероятно, поеду с x.find(5)->second, поскольку мне нужно отметить мою функцию const (карта является переменной-членом), а оператор [], очевидно, не позволяет что (поскольку он потенциально модифицирует карту, отсутствует ключ).

4b9b3361

Ответ 1

Взял это прямо из <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);
    }

О том же. Должна ли быть разница между:

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

и

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

Я бы так не подумал.

Ответ 2

Это не отвечает на ваш вопрос, но я хотел бы указать на некоторые проблемы с тем, как вы используете find.

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

Я не могу комментировать, что быстрее. Но я могу с уверенностью сказать, что первый подход безопасен!

Что делать, если карта не содержит данный ключ?

В первом подходе он создает новый pair с заданным ключом и инициализирует значение со значением по умолчанию double (которое равно нулю) и возвращает его.

Но второй аспект? find вернет map::end, если указанный ключ не найден в контейнере, и вы разыскиваете его. Авария программы!

Правильный способ использования find:

std::map<long, double>::iterator it;    
if ( (it = x.find(key)) != x.end() )
{
    double value = it->second;
}

Ответ 3

Первое присваивание с помощью operator[] должно выполнить одно и то же разыменование для получения значения, которое явно указано в find()->second. Вы можете настроить профиль, чтобы быть уверенным, но производительность должна быть достаточно близка к тому, что вы должны использовать форму, которая является наиболее ясной в вашем коде.