DevPrep

Все темы › Современный Swift

Как компилятор Swift оптимизирует вызовы (девиртуализация, WMO)?

Senior PRO

Суть

Динамический вызов (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

Потренируйтесь перед собеседованием

В DevPrep эти ответы превращаются в задачи на минуту: что напечатает код, найди баг, пробное собеседование. По задаче в день.

Скачать DevPrep в App Store