Разработка
Как iOS 16 ускоряет запуск вашего приложения
Эти улучшения сводятся к изменениям в dyld — программе, отвечающей за загрузку вашего приложения и выполнение его кода.
В State of the Union на WWDC22 был сделан анонс, который обещал значительно улучшить время запуска приложений:
такие приложения, как Lyft или Airbnb, запускаются почти в два раза быстрее благодаря улучшению в динамическом компоновщике.
Это улучшение связано с ускорением проверок протоколов, которые были медленными. Кроме того, в iOS 16 сокращается время загрузки двоичного файла за счет уменьшения объема данных, загружаемых с диска. Об этом вы также можете прочитать в предыдущей статье.
Эти улучшения сводятся к изменениям в dyld — программе, отвечающей за загрузку вашего приложения и выполнение его кода. Они также используют два противоположных (но распространенных) подхода к повышению производительности — активную загрузку (eager loading) и ленивую оценку (lazy evaluation).
В этой статье мы рассмотрим, что изменилось в iOS 16, насколько она на самом деле быстрее и как вы можете наилучшим образом использовать эти новые функции в своем приложении.
Протокольные проверки
Проверки соответствия протоколу происходят в рантайме Swift, чтобы определить результат кода, такого как, например, myVar as? MyProtocol. Каждый раз, когда тип соответствует протоколу, двоичный файл будет включать «запись о соответствии». При проверке соответствия среда выполнения перебирает каждую запись о соответствии, чтобы проверить, соответствует ли какая-либо из них текущей операции. Этот цикл имеет сложность O(n), где n — количество записей соответствия в вашем приложении. Для больших приложений их может быть более ста тысяч, что делает каждую проверку соответствия очень медленной.
Проверки соответствия протоколу широко распространены в приложениях Swift, даже если вы их не используете, потому что они также вызываются из обычных операций, таких как String(describing:) или AnyHashable. Для некоторых крупных приложений Swift, таких как Lyft и Airbnb, почти половина времени запуска тратится на проверку соответствия протоколу.
Большое изменение пришло с «замыканием dyld» (dyld closure), которое представляет собой кеш для каждого приложения, используемый для ускорения различных операций dyld во время запуска приложения. Замыкание теперь содержит предварительно вычисленные соответствия, что позволяет выполнять каждый поиск намного быстрее. Обратите внимание, что замыкание dyld используется не всегда, например, из-за того, что данные устарели, или потому, что приложение запускается из Xcode, что усложняет ситуацию. Это изменение было реализовано в проекте с открытым исходным кодом Swift в рамках PR Майка Эша, который добавил вызов API dyld: _dyld_find_protocol_conformance_on_disk. Если соответствие найдено в кеше, операция O(n) полностью пропускается, поэтому мы должны увидеть большие улучшения для приложений с большим количеством соответствий.
Тестирование
В Emerge мы проводим множество тестов производительности, чтобы определить, как пул-реквесты влияют на запуск приложения. Поэтому, естественно, мы хотели точно измерить, как эти предварительно рассчитанные проверки соответствия повлияют на время запуска.
Поскольку мы имеем дело с двумя разными версиями ОС, мы не можем тестировать на одном устройстве. Вместо этого я решил провести микротестирование времени проверки соответствия для приложения с 10 000, 20 000, 30 000, 40 000 и 50 000 соответствий в двоичном виде. Каждая версия запускается на устройстве с iOS 16 и iOS 15, при этом соответствие 10 000 считается базовым уровнем, и времена сравниваются с базовым уровнем.
Очевидно, что iOS 15 становится медленнее по мере добавления новых соответствий, а iOS 16 — нет, проблема решена! На практике замыкание не всегда будет доступно, поэтому нам придется подождать, пока iOS 16 не появится на пользовательских устройствах через несколько месяцев, чтобы точно знать, насколько это изменит цифры в продакшене. Это улучшение распространяется на все приложения, даже если их минимальная цель развертывания ниже iOS 16.
Отказы страниц
Второе большое улучшение связано с уменьшением объема данных, загружаемых с диска при запуске. При первом выполнении фрагмента кода ядро загружает окружающий его фрагмент памяти, известный как страница, в процессе, называемом отказом страниц (page fault). При запуске приложения необходимо исправить некоторые части бинарника, прежде чем код сможет работать (подробное объяснение этого в предыдущей статье в блоге). В iOS 15 все исправления выполнялись при запуске приложения, а это означает, что любое место в двоичном файле, требующее исправления, должно было быть загружено со своей страницей. Теперь новая функция, называемая связыванием страниц, разрешает исправления лениво, только при первом доступе к странице.
В прошлом году на WWDC представили новый крупный формат метаданных, используемых для выполнения этих исправлений, которые я подробно рассмотрел в то время. Этот формат необходим для ленивой оценки исправлений, поэтому пользователи iOS 16 получат его, только если вы ориентируетесь на iOS 13.4 или более позднюю версию.
Тестирование
В iOS 15 все сегменты __DATA и __DATA_CONST двоичного файла содержат исправления, поэтому общее количество page fault на время запуска вашего кода равно размеру этих сегментов. С помощью инструментов Emerge мы также можем измерить, сколько страниц необходимо запустить вашему коду, разница показывает, насколько меньше отказов страниц у вас будет в iOS 16.
Получение всей выгоды
Это большое улучшение, которое сразу же снижает количество отказов страниц, но есть способы добиться еще большего сокращения. Emerge предлагает службу упорядочивания файлов — Launch Booster — которая автоматически упорядочивает двоичные файлы, чтобы свести к минимуму отказы страниц. Мы улучшаем время запуска в среднем на 18% при развертывании упорядоченного файла в магазине приложений на iOS 15. Теперь, когда iOS 16 не загружает каждую страницу автоматически, упорядоченный двоичный файл может еще больше ускорить запуск вашего приложения! Если вы хотите узнать больше о том, как вы можете автоматически сократить время запуска и воспользоваться преимуществами улучшений iOS 16, свяжитесь с командой Emerge.