Вопрос проверяет понимание низкоуровневых причин производительности и связи модели памяти с быстродействием кода.
Стек быстрее кучи, потому что управление памятью в стеке максимально простое. Выделение и освобождение памяти сводится к изменению указателя стека. В куче требуется поиск подходящего блока памяти и синхронизация. Также стек лучше использует кэш процессора. Всё это делает операции со стеком значительно быстрее.
Разница в скорости между стеком и кучей связана не с языком программирования, а с устройством памяти и правилами её использования.
В стеке:
память выделяется последовательно
освобождение происходит автоматически при выходе из области видимости
не требуется поиск свободного блока
Фактически операция выглядит как:
сдвиг указателя стека вперёд
сдвиг назад при выходе из функции
Это крайне дешёвые операции.
В куче ситуация иная:
память выделяется динамически
нужно найти подходящий участок
требуется учёт фрагментации
часто нужна синхронизация между потоками
Кроме того, в iOS:
heap тесно связан с ARC
увеличение и уменьшение счётчика ссылок тоже имеет стоимость
Стек:
обычно компактный
имеет хорошую пространственную локальность
эффективно попадает в CPU cache
Heap:
может быть фрагментирован
объекты разбросаны в памяти
хуже кэшируется
Поэтому в Swift:
value types стараются размещать в стеке
копирование значений часто дешевле, чем кажется
классы используются осознанно
Стек быстрее кучи из-за простой модели управления памятью и лучшей работы с кэшем. Heap гибче, но эта гибкость оплачивается производительностью.