Обзор базовых профилей

Базовые профили повышают скорость выполнения кода примерно на 30 % с момента первого запуска за счет исключения этапов интерпретации и JIT- компиляции для включенных путей кода.

Отправляя базовый профиль в приложение или библиотеку, среда выполнения Android (ART) может оптимизировать указанные пути кода посредством предварительной компиляции (AOT), обеспечивая повышение производительности для каждого нового пользователя и каждого обновления приложения. Эта управляемая оптимизация по профилю (PGO) позволяет приложениям оптимизировать запуск, уменьшить количество зависаний при взаимодействии и повысить общую производительность выполнения для пользователей с первого запуска.

Такое повышение производительности напрямую приводит к улучшению бизнес-показателей, таких как удержание пользователей, транзакции и рейтинги. Подробнее о том, как производительность влияет на бизнес-показатели, вы можете прочитать в историях Джоша , Lyft , TikTok и Zomato .

Преимущества базовых профилей

Базовые профили делают все взаимодействия с пользователем, такие как запуск приложений, навигация между экранами или прокрутка контента, более плавными с первого запуска. Повышая скорость и оперативность приложения, базовые профили могут привести к увеличению числа активных пользователей в день и повышению среднего показателя повторных посещений.

Базовые профили помогают проводить оптимизацию помимо запуска приложения, обеспечивая общие взаимодействия с пользователем, которые улучшают время работы приложения с первого запуска. Управляемая компиляция AOT не зависит от пользовательских устройств и может выполняться один раз для каждого выпуска на компьютере разработки, а не на мобильном устройстве. При выпуске выпусков с базовым профилем оптимизация приложений становится доступной гораздо быстрее, чем при использовании только облачных профилей .

Если базовый профиль не используется, весь код приложения либо JIT-компилируется в памяти после интерпретации, либо записывается в файл odex в фоновом режиме, когда устройство находится в режиме ожидания. После установки или обновления приложения пользователи испытывают неоптимальные впечатления с момента его первого запуска до тех пор, пока не будут оптимизированы новые пути кода. Во многих приложениях после оптимизации производительность увеличивается примерно на 30%.

Профили запуска

Профили запуска похожи на базовые профили, но разница в том, что они используются во время компиляции, а не для оптимизации на устройстве. Профиль запуска используется для оптимизации структуры файла DEX и сокращения времени запуска. Код, указанный в профиле запуска, помещается в основной classes.dex , а остальной код — в отдельные файлы DEX. Это сокращает время запуска за счет уменьшения количества ошибок страниц во время запуска приложения. Чтобы узнать больше о том, как профили запуска и оптимизация макета DEX могут сократить время запуска приложений, см. раздел Оптимизация макета DEX и профили запуска .

Начать

Чтобы начать оптимизацию производительности существующего приложения, см. раздел Создание базовых профилей .

Цепочка зависимостей обеспечивает стабильные и разрабатываемые версии. Чтобы создать и установить базовый профиль, используйте следующие поддерживаемые версии или более поздние версии плагина Android Gradle, библиотеки Macrobenchmark и установщика профиля. Эти зависимости требуются в разное время и работают вместе как цепочка инструментов для обеспечения оптимального базового профиля.

  • Плагин Android Gradle: com.android.tools.build:8.0.0
  • Библиотека макробенчмарков: androidx.benchmark:benchmark-macro-junit4:1.3.1
  • Установщик профиля: androidx.profileinstaller:profileinstaller:1.4.0

Мы рекомендуем использовать последнюю версию AGP для создания базовых профилей и управления ими. Вот основные функции, которые имеются в различных версиях AGP:

AGP-версия Функции
8.4 Установка локальных приложений неотлаживаемых сборок с помощью инструмента командной строки оболочки Gradle или базовых профилей установки Android Studio, поэтому производительность сборки локального выпуска более точно соответствует производственной. Это обновление не влияет на производственную производительность базовых профилей.
8.3
  • Полная поддержка каталогов исходного набора (библиотечные модули): объявите несколько исходных файлов базового профиля и используйте каталоги с поддержкой вариантов, такие как src/free/generated/baselineProfiles/baseline-prof1.txt , теперь для библиотечных модулей, а также модулей приложений.
  • Базовые профили включают очищенные классы .
8.2
  • Переписывание правил R8: D8 и R8 могут преобразовать удобочитаемые правила базового плана и стартового профиля, чтобы полностью охватить все правила, необходимые для оптимизации производительности приложения. Увеличивает охват методов базового профиля примерно на 30 % и повышает производительность приложения примерно на 15 %.
  • Профили запуска: создайте этот новый тип базового профиля, чтобы определить структуру кода в DEX. Увеличивает производительность при запуске дополнительно примерно на 15% или значительно больше для больших приложений.
8.0 Минимальная рекомендуемая версия: используйте плагин Gradle Baseline Profile для создания базовых профилей с помощью одной задачи Gradle.
  • Полная поддержка каталогов исходного набора (модули приложения): объявите несколько исходных файлов базового профиля и используйте каталоги с поддержкой вариантов, такие как src/free/generated/baselineProfiles/baseline-prof1.txt .
7.4 Минимальная поддерживаемая версия: приложения могут использовать базовые профили из библиотек и предоставлять свой собственный базовый профиль в файле src/main/baseline-prof.txt .
  • Базовые профили правильно упаковываются при сборке APK из пакета приложения ( проблема № 230361284 ).
  • Для приложений с несколькими файлами .dex базовые профили правильно упаковываются для основного файла .dex .

Пример создания профиля

Ниже приведен пример класса для создания базового профиля для запуска приложения, а также нескольких событий навигации и прокрутки с использованием рекомендуемой библиотеки Macrobenchmark :

@OptIn(ExperimentalBaselineProfilesApi::class)
class BaselineProfileGenerator {
    @get:Rule
    val baselineProfileRule = BaselineProfileRule()

    @Test
    fun appStartupAndUserJourneys() {
        baselineProfileRule.collect(packageName = PACKAGE_NAME) {
            // App startup journey.
            startActivityAndWait()

            device.findObject(By.text("COMPOSE LAZYLIST")).clickAndWait(Until.newWindow(), 1_000)
            device.findObject(By.res("myLazyColumn")).also {
                it.fling(Direction.DOWN)
                it.fling(Direction.UP)
            }
            device.pressBack()
        }
    }
}

Вы можете увидеть этот код в полном контексте и более подробно в наших примерах производительности на GitHub .

Что включить

При использовании базовых профилей в приложении вы можете включать код запуска приложения и общие действия пользователя, такие как навигация между экранами или прокрутка. Вы также можете собирать целые потоки, такие как регистрация, вход в систему или оплата. Любые пользовательские маршруты, которые вы считаете критически важными, могут получить выгоду от базовых профилей за счет улучшения их производительности во время выполнения.

Если вы экспериментируете с различными подходами к повышению производительности, рассмотрите возможность включения базовых профилей в обе части вашего эксперимента. Сделав это, вы облегчите интерпретацию результатов, гарантируя, что все ваши пользователи последовательно запускают скомпилированный код.

Библиотеки могут предоставлять свои собственные базовые профили и поставлять их вместе с выпусками для повышения производительности приложений. Например, см. раздел «Использование базового профиля» в разделе «Производительность Jetpack Compose» .

Как работают базовые профили

При разработке приложения или библиотеки рассмотрите возможность определения базовых профилей, чтобы охватить типичные взаимодействия с пользователем, где важны время рендеринга или задержка. Вот как они работают:

  1. Удобные для чтения правила профиля генерируются для вашего приложения и компилируются в двоичной форме в приложении. Вы можете найти их в assets/dexopt/baseline.prof . Затем вы можете загрузить AAB в Google Play, как обычно.

  2. Google Play обрабатывает профиль и отправляет его непосредственно пользователям вместе с APK. Во время установки ART выполняет AOT-компиляцию методов профиля, в результате чего эти методы выполняются быстрее. Если профиль содержит методы, используемые при запуске приложения или во время рендеринга кадров, пользователь может столкнуться с более быстрым запуском и меньшим количеством зависаний.

  3. Этот поток взаимодействует с агрегацией облачных профилей для точной настройки производительности на основе фактического использования приложения с течением времени.

Рисунок 1. На этой диаграмме показан рабочий процесс базового профиля от загрузки до доставки конечному пользователю, а также то, как этот рабочий процесс связан с облачными профилями.

Облачные профили

Облачные профили предлагают дополнительную форму PGO, агрегируемую Google Play Store и распространяемую для компиляции во время установки, вместе с базовыми профилями.

Хотя облачные профили основаны на реальном взаимодействии пользователей с приложением, их распространение занимает от нескольких часов до нескольких дней после распространения обновления, что ограничивает их доступность. Пока профили не будут полностью распространены, производительность приложений будет неоптимальной для пользователей новых или обновленных приложений. Кроме того, облачные профили поддерживают только устройства Android под управлением Android 9 (уровень API 28) или выше и хорошо масштабируются только для приложений с достаточно большой базой пользователей.

Поведение компиляции в разных версиях Android

В версиях платформы Android используются разные подходы к компиляции приложений, каждый из которых имеет соответствующий компромисс в производительности. Базовые профили улучшают предыдущие методы компиляции, предоставляя профиль для всех установок.

Android-версия Метод компиляции Оптимизационный подход
От 5 до 6 (уровни API от 21 до 23) Полный АОТ Все приложение оптимизируется во время установки, что приводит к длительному времени ожидания использования приложения, увеличению использования оперативной памяти и дискового пространства, а также увеличению времени загрузки кода с диска, что потенциально увеличивает время холодного запуска.
От 7 до 8,1 (уровень API от 24 до 27) Частичный AOT (базовый профиль) Базовые профили устанавливаются с помощью androidx.profileinstaller при первом запуске, когда модуль приложения определяет эту зависимость. ART может улучшить эту ситуацию, добавив дополнительные правила профиля во время использования приложения и компилируя их, когда устройство находится в режиме ожидания. Это оптимизирует дисковое пространство и время загрузки кода с диска, тем самым сокращая время ожидания приложения.
9 (уровень API 28) и выше Частичная AOT (базовый уровень + облачный профиль) Play использует базовые профили во время установки приложения для оптимизации профилей APK и Cloud (если они доступны). После установки профили ART загружаются в Play, объединяются, а затем предоставляются в виде облачных профилей другим пользователям при установке или обновлении приложения.

Известные проблемы

Ниже приведены возможные проблемы и решения или проблемы, для которых в настоящее время разрабатываются обходные пути:

  • Создание базового профиля может завершиться неудачно из-за настроек разрешений на некоторых устройствах, включая устройства OnePlus. Чтобы обойти эту проблему, отключите параметр «Отключить мониторинг разрешений» в настройках «Параметры разработчика» .

  • Генерация базового профиля не поддерживается на устройствах Firebase Test Lab, включая устройства Test Lab, управляемые Gradle ( проблема № 285187547 ).

  • Чтобы успешно предоставить базовые профили для библиотек, используйте плагин Gradle Baseline Profile 1.2.3 или AGP 8.3 как минимум ( проблема № 313992099 ).

  • Если вы создаете базовые профили с помощью команды ./gradlew app:generateBaselineProfile , тесты в тестовом модуле также выполняются, а результаты отбрасываются. В этом случае вы можете создать только базовые профили, выполнив команду с -P android.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile . Эта проблема исправлена ​​в AGP 8.2.

  • Команда для создания базовых профилей для всех типов сборки ./gradlew app:generateBaselineProfile — создает базовые профили только для типа сборки выпуска. Эта проблема исправлена ​​в AGP 8.1.

  • Каналы распространения приложений, не относящиеся к Google Play Store, могут не поддерживать использование базовых профилей при установке. Пользователи приложений, установленных через эти каналы, не увидят преимуществ до тех пор, пока не запустится фоновая dexopt, что, скорее всего, произойдет в одночасье.

  • Внутренний общий доступ к приложениям в Play Store не поддерживает базовые профили; однако внутреннее тестирование дает такую ​​возможность.

  • Оптимизация батареи на некоторых устройствах, например устройствах Huawei, может помешать установке профиля. Чтобы обеспечить эффективную установку профилей, отключите любую оптимизацию батареи на тестовых устройствах.

Дополнительные ресурсы

{% дословно %} {% дословно %} {% дословно %} {% дословно %}