std :: map insert && перегрузка вызывает копирование - PullRequest
0 голосов
/ 17 мая 2018

Глядя на этот интересный доклад:

CppCon 2017: Мэтт Кулукундис «Разработка быстрой, эффективной и удобной для кэширования таблицы хэширования, шаг за шагом»

Оноколо минуты 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, верно?Может ли кто-нибудь просветить меня?

Ответы [ 2 ]

0 голосов
/ 17 мая 2018
  1. Перегрузка шаблона называется ( перегрузка (2) для cppreference )
  2. Перегрузка шаблона эквивалентна emplace
  3. emplace isне медленнее, чем insert, и быстрее в общем случае, но ...

Но, emplace допускает одно злоупотребление, то есть когда вы неоднократно пытаетесь вставить один и тот же ключ.И тест делает именно это (обратите внимание, что while).Я бы сказал, что это просто эталон, показывающий поведение, когда вы намеренно стреляете себе в ногу.В реальном мире я не думаю, что можно было бы сделать это через emplace или insert.

В C ++ 17 это было исправлено 1 способом, который требует изменения вашего кода:

  1. try_emplace функция https://isocpp.org/files/papers/n4279.html
0 голосов
/ 17 мая 2018

Вы не принимаете проблемные перегрузки:

std::pair<iterator,bool> insert(const value_type& value); // (1)

template< class P >
std::pair<iterator,bool> insert(P&& value); // (2)

P, выведенные как value_type&.

...