C ++ карта :: найти и карта :: при разнице в производительности - PullRequest
0 голосов
/ 23 октября 2018

Я выполнял некоторые упражнения по определенной программе, хотя алгоритм казался правильным, он был бы слишком медленным (и я имею в виду слишком медленный).Программа обращалась к карте, используя map::at (введено в C ++ 11).С минимальным изменением замены at на find (и исправлением синтаксиса) одна и та же программа будет действительно быстрой (по сравнению с исходной версией).

Глядя на cplusplus.com, оба метода утверждают, что имеюттакой же сложности, и я не мог понять, почему одно будет отличаться от другого (кроме причины API, не вызывая исключения и т. д.).

Затем я увидел, что описание в разделе о гонках данныхразные.Но я не до конца понимаю последствия.Правильно ли мое предположение, что map::at является поточно-ориентированным (тогда как map::find - нет) и, следовательно, влечет за собой некоторые штрафы за время выполнения?

http://www.cplusplus.com/reference/map/map/at/

http://www.cplusplus.com/reference/map/map/find/

Edit

Оба находятся в цикле, который вызывается 10.000.000 раз.Нет флагов оптимизации.Просто g++ foo.cpp.Здесь diff (arrayX - векторы, m - карта)

<               auto t = m.find(array1.at(i));
<               auto t2 = t->second.find(array2.at(i));
<               y = t->second.size();
<               cout << array.at(i) << "[" << t2->second << " of " << y << "]" << endl;
---
>               auto t = m.at(array1.at(i));
>               x = t.at(array2.at(i));
>               y = m.at(array1.at(i)).size();
>               cout << array.at(i) << "[" << x << " of " << y << "]" << endl;

1 Ответ

0 голосов
/ 24 октября 2018

Наблюдаемая разница в производительности может объясняться копированием объекта .

auto t = m.at(array1.at(i));

В соответствии с правилом вычета аргументов шаблона (то же самое применяется для *Спецификатор 1008 *), в приведенном выше операторе t выводится в mapped_type, что вызывает копирование объекта.

Вам необходимо определить t как auto& t, чтобы оно было выведено в mapped_type&.

Связанный разговор: `авто` указание типа спецификатора для ссылок

...