How does the Swift compiler optimize calls (devirtualization, WMO)?
The idea
A dynamic call (vtable, witness table, objc_msgSend) is an indirect jump that cannot be inlined and behind which the optimizer sees no code. So in -O the compiler tries to prove which implementation will be called and replace the dynamic call with a direct one — that is devirtualization. The more the compiler can see, the more often it succeeds.
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") // type known → direct call, inlined
let base: Logger = console
base.log("hi") // vtable; with WMO the compiler sees all subclasses
The rest of this answer, with code and interview follow-ups, is in the DevPrep app.
Read the full answer in DevPrep