Я недавно увидел класс Util
, написанный моим другом, который так много inline
методов. Класс много об изображениях и имеет такие методы, какКакова польза от метода наложения
public static inline function resize (img:Image, width:Int, height:Int)
{
//... method implementation goes here.
}
Я спросил его, почему использование inline
. Я знаю, что компилятор изменяет
var img:Image = ImgUtil.resize(img, 100, 100);
в
var img:Image = // Implementation of method here
Он просто сказал, что он уменьшает вызовы функций и использовать их только на вспомогательных методов. Не копирует один и тот же код каждый раз, увеличивая размер программы?
Нужно ли это сейчас? При необходимости, когда их следует использовать?
EDIT
я перечисляю большинство проблем и преимуществ в виде списка, приведенного в ссылке Patrick при условии, чтобы помочь будущим зрителям, которые не хотят, чтобы пройти через ссылки.
Проблемы
Замена сайта вызова с расширенным телом функции может ухудшить производительность несколькими способами:
- В тех случаях, когда размер кода является более важным, чем скорость, например, многих встраиваемых систем, как правило, невыгодно, за исключением очень малых функций, таких как тривиальные мутаторные методы.
- Увеличение размера кода может привести к тому, что небольшая критическая часть кода больше не будет входить в кеш, что приведет к провалу кеша и замедлению.
- Добавленные переменные из встроенной процедуры могут потреблять дополнительные регистры, а в области, где давление в регистре уже высока, это может привести к проливанию, что вызывает дополнительные обращения к ОЗУ.
- Спецификация языка может позволить программе делать дополнительные предположения о аргументах процедурам, которые она больше не может выполнять после того, как процедура встроена.
- Если размер кода увеличен слишком сильно, ограничения ресурсов, такие как размер ОЗУ, могут быть превышены, что приведет к программам, которые либо не могут быть запущены, либо вызваны сбоем. Сегодня это вряд ли будет проблемой для настольных или серверных компьютеров, за исключением очень агрессивной встраивания, но это все равно может быть проблемой для встроенных систем.
Как правило, разработчики компилятора учитывают эти проблемы и включают эвристику в свои компиляторы, которые в большинстве случаев выбирают, какие функции встроены, чтобы повысить производительность, а не ухудшать ее.
Преимущество:
Инлайн само расширения является оптимизацией, поскольку она исключает накладные расходы от звонков, но это гораздо более важно, как благоприятная трансформация. То есть, как только компилятор расширяет тело функции в контексте своего сайта вызова - часто с аргументами, которые могут быть фиксированными константами, - он может выполнять множество преобразований, которые ранее были невозможны.Например, условная ветвь может оказаться всегда верной или всегда ложной на этом конкретном сайте вызова. Это, в свою очередь, может включать устранение мертвого кода, циклическое преобразование кода или исключение индукционной переменной.
Спасибо за ссылку. Я скажу, что мой друг говорит, что 'ininining обычно невыгодно, за исключением очень маленьких функций, таких как тривиальные методы мутатора'. Поскольку его методы длинны и связаны с некоторыми циклами. –