По словам Скотта Мейерса, одна из областей, где C ++ сияет над C, заключается в том, что функциональные объекты работают быстрее, чем указатели на функции. Он говорит, что это потому, что функциональные объекты встроены, что увеличивает скорость.
У меня есть два вопроса по этому поводу:
Как мы можем проверить, что функциональные объекты на самом деле являются встроенными? Можем ли мы проверить это на практике?
Зависит ли встраивание функциональных объектов от компилятора, который мы используем, или все компиляторы ведут себя так?
Стандарты 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
,
- Как мы можем проверить, что функциональные объекты на самом деле встроены? Можем ли мы проверить это на практике?
Конечно, проверьте окончательно выпущенный ассемблерный код.
- Функции встроенных функций зависят от того, какой компилятор мы используем, или все компиляторы ведут себя так?
Это сильно зависит от реализации компилятора и уровня оптимизации.
Так что нет, нет гарантии, что определенные компиляторы (линкеры) будут вести себя так.
Вызовы через указатели функций не могут быть встроенными.
По его словам, функциональные объекты встроены, поэтому происходит увеличение скорости.
IMO «функциональные объекты встроены» лучше почитать (или слышать, я не знаю, откуда этот цитата):
функциональные объекты может быть встроен пока вызовы через указатели функций не могут.
Да, функциональные объекты могут привести к более быстрому коду. Но единственный способ обеспечить это — это сравнительный анализ.
документация говорит:GCC может все еще быть не в состоянии встроить функцию по многим причинам; -Winline
опция может быть использована для определения, если функция не была встроена и почему нет.«
Конечно, это будет зависеть от компилятора, версии, флагов и т. Д. Иногда встраивание может быть непродуктивным (раздувание кода и т. Д.), Поэтому у каждого компилятора есть свой собственный набор правил, чтобы решить, должна ли функция быть встроенной. Кстати, inline
ключевое слово является только подсказкой, а некоторые библиотеки, такие как собственный трудно навязать встраивание.