Как компилятор Swift оптимизирует вызовы (девиртуализация, WMO)?
Суть
Динамический вызов (vtable, witness table, objc_msgSend) — это косвенный переход, который нельзя заинлайнить и за которым оптимизатор не видит кода. Поэтому компилятор в -O старается доказать, какая реализация будет вызвана, и заменить динамический вызов прямым — это девиртуализация. Чем больше компилятор видит, тем чаще у него получается.
class Logger {
func log(_ s: String) { print(s) }
}
final class ConsoleLogger: Logger {
override func log(_ s: String) { print("console:", s) }
}
let console = ConsoleLogger()
console.log("hi") // тип известен → прямой вызов, инлайн
let base: Logger = console
base.log("hi") // через vtable; с WMO компилятор видит все подклассы
Продолжение ответа с кодом и уточняющими вопросами интервьюера — в приложении DevPrep.
Полный ответ — в DevPrep