Какой тип диспетчеризации в программировании самый медленный и почему?

«Какой тип диспетчеризации в программировании самый медленный и почему?» — вопрос из категории ООП, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Динамическая диспетчеризация (dynamic dispatch) — самый медленный тип, поскольку определение вызываемого метода происходит во время выполнения программы (runtime), а не на этапе компиляции.

Почему он медленный:

  1. Поиск в таблице методов: Требуется обращение к таблице виртуальных методов (vtable) или аналогичной структуре для определения адреса реализации.
  2. Отсутствие оптимизаций компилятора: Компилятор не может применить ключевые оптимизации, такие как инлайнинг (подстановка кода функции) или девиртуализация.
  3. Проблемы с предсказанием ветвлений: Процессору сложно предсказать, какой код будет выполнен, что приводит к сбросам конвейера команд.

Пример на Swift (протокол):

protocol Drawable {
    func draw()
}

struct Circle: Drawable {
    func draw() { print("Рисую круг") }
}

struct Square: Drawable {
    func draw() { print("Рисую квадрат") }
}

// Компилятор не знает точный тип `shape` во время компиляции
let shape: Drawable = Bool.random() ? Circle() : Square()
shape.draw() // Динамический вызов: поиск метода `draw` в runtime

Когда использовать: Для полиморфизма, когда тип объекта неизвестен на этапе компиляции (работа через протоколы или базовые классы). Что использовать для производительности: Статическую диспетчеризацию (структуры, final-классы, generic-параметры), где вызов метода разрешается на этапе компиляции.