Могу ли я выборочно (принудительно) встроить функцию? - PullRequest
22 голосов
/ 18 августа 2011

В книге Чистый код (и пару других, с которыми я сталкивался и читал), предлагается сохранять функции небольшими и разбивать их, если они становятся большими.Также предлагается, чтобы функции выполняли одно и только одно.

В Оптимизация программного обеспечения на C ++ Агнер Фог заявляет, что ему не нравится правило разбиения функции только потому, что оно пересекаетопределенный порог количества строк.Он заявляет, что это приводит к ненужным скачкам, которые ухудшают производительность.

Прежде всего, я понимаю, что не будет иметь значения, если код, над которым я работаю, не находится в узком цикле и что функции тяжелы, так чтовремя, требуемое для их вызова, уменьшается по сравнению с временем выполнения кода в функции.Но давайте предположим, что я работаю с функциями, которые в большинстве случаев используются другими объектами / функциями и выполняют относительно тривиальные задачи.Эти функции следуют рекомендациям, перечисленным в первом абзаце (то есть выполняют одну единственную функцию и являются небольшими / понятными).Затем я начинаю программировать критически важную для производительности функцию, которая использует эти другие функции в замкнутом цикле и по существу является функцией кадра.Наконец, предположим, что их встраивание имеет преимущество для критически важной для производительности функции, но не дает никакой выгоды для любой другой функции (да, я это профилировал, хотя с большим количеством копий и вставок, которых я хочу избежать).

Сразу можно сказать, что пометить функцию inline и позволить компилятору выбирать.Но что, если я не хочу, чтобы все эти функции были в файле ` .inl или отображались в заголовке?В моей нынешней ситуации все критически важные для производительности функции и другие используемые им функции находятся в одном исходном файле.

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

Ответы [ 6 ]

16 голосов
/ 18 августа 2011

Ничто не мешает вам поместить inline в статическую функцию в файле .cpp.

В некоторых компиляторах есть возможность принудительно включить встроенную функцию, см., Например, GCC атрибут ((всегда_инлайн)) и множество вариантов тонкой настройки оптимизации (см. -Minline- * параметры).

Моя рекомендация - использовать inline илиеще лучше static inline , где вы считаете нужным, и пусть компилятор решит.Они обычно делают это очень хорошо.

11 голосов
/ 18 августа 2011

Вы не можете принудительно встроить. Кроме того, вызовы функций на современных процессорах довольно дешевы по сравнению со стоимостью проделанной работы. Если ваши функции достаточно велики, чтобы их можно было разбить, дополнительное время, необходимое для выполнения вызова, по существу не будет иметь значения.

Если это не удастся, вы можете ... попробовать ... использовать макрос.

11 голосов
/ 18 августа 2011

Нет, inline - это рекомендация для компилятора; это не заставляет его делать что-либо. Кроме того, если вы работаете с MSVC ++, обратите внимание, что __forceinline также является неправильным; это просто более сильная рекомендация, чем inline.

6 голосов
/ 28 ноября 2012

Это столько же о старомодном добром C, сколько и о C ++. Я размышлял об этом на днях, потому что во встроенном мире, где нужно тщательно управлять скоростью и пространством, это может иметь значение (в отличие от слишком часто ", не беспокойтесь об этом, ваш компилятор умный и дешевая память распространена в разработке настольных компьютеров / серверов).

A возможное решение, которое мне еще предстоит проверить, состоит в том, чтобы в основном использовать два имени для разных вариантов, что-то вроде

inline int _max(int a, int b) {
    return a > b ? a : b;
}

, а затем

int max(int a, int b) {
    return _max(a, b);
}

Это дало бы возможность выборочно вызывать _max () или max (), но при этом алгоритм был определен один раз и только один раз.

1 голос
/ 01 марта 2017

Inlining - Например, если существует функция A, которая часто вызывает функцию B, а функция B относительно мала, то оптимизация на основе профиля включит функцию B в функцию A.

VS Оптимизация по профилю

Вы можете использовать автоматизированный плагин управляемого профиля для Visual C ++ в Центре производительности и диагностики, чтобы упроститьи оптимизировать процесс оптимизации в Visual Studio, или вы можете выполнить шаги оптимизации вручную в Visual Studio или в командной строке. Мы рекомендуем подключаемый модуль, поскольку его проще использовать. Информацию о том, как получить подключаемый модуль и использовать его для оптимизации вашего приложения, см. В Подключаемом модуле оптимизации профиля .

1 голос
/ 18 августа 2011

Компиляторы действительно очень хороши в генерации оптимизированного кода.

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

...