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
(карта является переменной-членом), а оператор []
, очевидно, не позволяет что (поскольку он потенциально модифицирует карту, отсутствует ключ).
Ответы
Ответ 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
. Вы можете настроить профиль, чтобы быть уверенным, но производительность должна быть достаточно близка к тому, что вы должны использовать форму, которая является наиболее ясной в вашем коде.