Действительно ли функторы быстрее, чем указатели на функции?

По словам Скотта Мейерса, одна из областей, где C ++ сияет над C, заключается в том, что функциональные объекты работают быстрее, чем указатели на функции. Он говорит, что это потому, что функциональные объекты встроены, что увеличивает скорость.

У меня есть два вопроса по этому поводу:

  1. Как мы можем проверить, что функциональные объекты на самом деле являются встроенными? Можем ли мы проверить это на практике?

  2. Зависит ли встраивание функциональных объектов от компилятора, который мы используем, или все компиляторы ведут себя так?

58

Решение

Стандарты C ++ и C оставляют большую свободу для компиляторов. Компиляторы могут считать до 1 миллиарда между каждой инструкцией или делать это только в том случае, если целое число содержит простое значение.

Приличные «настоящие» компиляторы этого не делают. Это вопрос качества реализации.

Включение функциональных объектов во что-то вроде std::sort это то, что делает каждый настоящий компилятор. Чрезвычайно легко обнаружить то, что должно быть встроено в этих случаях, потому что информация о типе несет с собой код, который должен быть встроен.

Делать это с помощью указателя на функцию сложнее. Это делается с помощью указателя на функцию, где все было преобразовано в void* или же char* указатели еще сложнее.

Результатом этого является то, что на практике вызов в стиле C qsort против C ++ — стиль вызова std::sort может привести к большому преимуществу для std::sort,

qsort примерно в 2 раза медленнее, чем std::sort, как показано Вот, в смехотворно простой ситуации сортировки случайно расположенных целых чисел.

Проверка фактического вывода кода сборки — это, главным образом, деталь, и для небольшой отдачи требуется много работы. Взяв конкретные примеры из реальной жизни, вы получите представление о том, насколько велико влияние на самом деле.

Все 3 из Clang, GCC и MSVC, где можно сделать std::sort быть значительно быстрее, чем их qsort, И поскольку это простая оптимизация, а оптимизация указателей функций на встроенные вызовы — нет, можно ожидать, что менее крупные компиляторы будут не лучше, чем в qsort,

76

Другие решения

  1. Как мы можем проверить, что функциональные объекты на самом деле встроены? Можем ли мы проверить это на практике?

Конечно, проверьте окончательно выпущенный ассемблерный код.

  1. Функции встроенных функций зависят от того, какой компилятор мы используем, или все компиляторы ведут себя так?

Это сильно зависит от реализации компилятора и уровня оптимизации.
Так что нет, нет гарантии, что определенные компиляторы (линкеры) будут вести себя так.

Вызовы через указатели функций не могут быть встроенными.


По его словам, функциональные объекты встроены, поэтому происходит увеличение скорости.

IMO «функциональные объекты встроены» лучше почитать (или слышать, я не знаю, откуда этот цитата):

функциональные объекты может быть встроен пока вызовы через указатели функций не могут.

18

Да, функциональные объекты могут привести к более быстрому коду. Но единственный способ обеспечить это — это сравнительный анализ.

  1. документация говорит:GCC может все еще быть не в состоянии встроить функцию по многим причинам; -Winline опция может быть использована для определения, если функция не была встроена и почему нет.«

  2. Конечно, это будет зависеть от компилятора, версии, флагов и т. Д. Иногда встраивание может быть непродуктивным (раздувание кода и т. Д.), Поэтому у каждого компилятора есть свой собственный набор правил, чтобы решить, должна ли функция быть встроенной. Кстати, inline ключевое слово является только подсказкой, а некоторые библиотеки, такие как собственный трудно навязать встраивание.

1
По вопросам рекламы [email protected]