Являются функторы на самом деле быстрее, чем указатели на функции?


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

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

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

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

3 58

3 ответа:

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

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

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

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

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

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

проверка фактического вывода кода сборки-это в основном деталь, и это много работы для небольшого возврата. Взятие конкретных реальных примеров дает вам представление о том, насколько велико влияние на самом деле.

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

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

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

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

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

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


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

ИМО "объекты функций встроены" лучше читать (или слышать, я не знаю, откуда эта цитата):

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

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

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

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