Ответ 1
Сначала я покажу вам волшебный трюк, как добиться этого без функции мусора. Затем я покажу вам, почему работает функция мусора. Итак, трюк:
Оригинал неэффективен (обратите внимание на мою машину примерно в два раза быстрее):
g++ -g -pipe -march=native -pedantic -std=c++11 -W -Wall -Wextra -Werror -O3 -o bin/inserter src/inserter.cc --param inline-unit-growth=200 && time ./bin/inserter
real 0m2.197s
user 0m2.200s
sys 0m0.000s
Теперь идет трюк (ваше определение все еще неактивно):
g++ -g -pipe -march=native -pedantic -std=c++11 -W -Wall -Wextra -Werror -O3 -o bin/inserter src/inserter.cc --param inline-min-speedup=2 && time ./bin/inserter
real 0m1.114s
user 0m1.100s
sys 0m0.010s
Примечание: разница в аргументе странного вида --param inline-min-speedup=2
Теперь я кратко опишу расследование:
-
В чем разница между быстрым и медленным? В медленной версии у нас есть неэффективный вызов
emplace_back_aux
внутриbar()
, который магически встроен, когда ваш foo раскоментирован. Таким образом, мы можем заключить, что бар очень горячий, и инкрустация здесь сложная. И, скорее всего, вся эта ошибка связана с вложением. -
Теперь с опцией
-fdump-ipa-inline-details
можно посмотреть на вставку дампов. Вы увидите разные соображения времени и размера. Трудно читать, и я не хочу вставлять сюда все подробности. Но общий результат изучения этой информации: GCC считает, что рост в размере модуля (в процентах) не стоит оценивать ускорение. -
Что делать? Две возможности:
3,1. Увеличьте размер модуля и общие оценки ускорения с помощью неиспользуемого кода
foo
, который использует правильные типы, такие как insert_iterator, чтобы вызвать emplace_back и коэффициент перемещения, чтобы быть больше, и достигнуть предела вложения (обратите внимание, что этот способ очень нестабилен - все может взорваться в других версии компилятора с улучшенными алгоритмами встраивания, и вам также должно быть действительно повезло, чтобы угадать, какой код работает).3,2. Или перейдите в листинг. Что я сказал GCC с предоставленным параметром, "рассмотрим возможность вложения даже больших функций с меньшим ускорением".
То есть. Есть много других параметров внутри GCC и других трюков, которые вы можете с ними сделать.