Глядя на этот интересный разговор:
Около минуты 38:32 он упоминает, что
void Benchmark_Slow(int iters) {
std::unordered_map<string, int> m;
std::pair<const string, int> p = {};
while (iters--) m.insert(p)
}
примерно в 2 раза медленнее, чем следующий вариант
void Benchmark_Fast(int iters) {
std::unordered_map<string, int> m;
const std::pair<const string, int> p = {};
while (iters--) m.insert(p)
}
Я все еще думаю о том, почему &&
перегрузка (1) будет выбрана.
std::pair<iterator,bool> insert( value_type&& value ); (1)
std::pair<iterator,bool> insert( const value_type& value ); (3)
где value_type
является std::pair<const Key, T>
,
Ведь мы не двигаем ценности, поэтому в моем понимании выражение p
должно быть lvalue, а не x / prvalue, верно? Может ли кто-нибудь просветить меня?
Вы не принимаете проблемные перегрузки:
std::pair<iterator,bool> insert(const value_type& value); // (1)
template< class P >
std::pair<iterator,bool> insert(P&& value); // (2)
P
выводится как value_type&
,
emplace
emplace
не медленнее, что insert
и скорее в общем случае, но …Но, emplace
допускает одно злоупотребление, и это когда вы неоднократно пытаетесь вставить один и тот же ключ. И тест делает именно это (обратите внимание, что while
). Я бы сказал, что это просто эталон, показывающий поведение, когда вы намеренно стреляете себе в ногу. В реальном мире я не думаю, что можно было бы сделать это через emplace
или же insert
,
В C ++ 17 это было исправлено одним способом, который требует изменения вашего кода:
try_emplace
функция https://isocpp.org/files/papers/n4279.html