10. Что такое inlining и зачем нужен @inline?Теория
Дополнительные вопросы
1. Какие недостатки есть у inlining?
2. Почему @inline не ставят на каждую функцию?
1. Какие недостатки есть у inlining?
2. Почему @inline не ставят на каждую функцию?
Inlining (инлайнинг) это подстановка тела функции на место вызова.
Обычно тело функции лежит отдельно в памяти программы. В месте вызова программа переходит к этому телу и потом возвращается.
При инлайнинге компилятор вместо перехода вписывает тело функции прямо в место вызова.
Чтобы управлять этим в Swift, используют атрибуты:
@inlinable. Нужен, когда функцию объявили в другом модуле, например в пакете SPM, а вызываем у себя. Тело попадает в интерфейс модуля, и компилятор нашей программы может подставить его на место вызова.@inline(__always). Просим компилятор использовать инлайнинг. Однако это не дает гарантии. Например, для рекурсивных функций и debug-сборок атрибут не сработает.@inline(never). Явно запрещаем инлайнинг.1. Поскольку при компиляции тело функции копируется в места вызова, бинарный файл программы разрастается.
2. Компилятор и так инлайнит короткие функции, где это выгодно. @inline(__always) на всё раздует код.
Inlining подставляет тело функции в место вызова. Пропадает сам вызов, и компилятор оптимизирует уже общий код.
@inline(__always) просит встроить всегда, @inline(never) запрещает. Это подсказки. Компилятор и без них встраивает маленькие функции, когда это выгодно.
1. Раздувается код: одно тело копируется в каждый вызов. Растёт бинарь, хуже попадает в кэш инструкций, дольше сборка. По шагам отладчика такой код тоже читать труднее.
2. Крупную функцию встраивать вредно, а маленькую компилятор и так часто встроит. @inline(__always) на всех вызовах раздувает модуль. Публичный метод библиотеки через границу модуля часто нельзя встроить: у клиента нет тела.