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

Базовые профили повышают скорость выполнения кода примерно на 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
  • Библиотека Macrobenchmark: androidx.benchmark:benchmark-macro-junit4:1.3.4
  • Установщик профиля: androidx.profileinstaller:profileinstaller:1.4.1

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

AGP-версия Функции
8.4 Локальные установки приложений неотлаживаемых сборок с помощью инструмента командной строки Gradle Wrapper или Android Studio устанавливают базовые профили, благодаря чему производительность локальной сборки релиза будет максимально приближена к производительности в рабочей среде. Это обновление не влияет на производительность базовых профилей в рабочей среде.
8.3
  • Полная поддержка каталогов исходных наборов (модули библиотеки): объявляйте несколько исходных файлов Baseline Profile и используйте каталоги с поддержкой вариантов, такие как src/free/generated/baselineProfiles/baseline-prof1.txt , теперь как для модулей библиотеки, так и для модулей приложений.
  • Базовые профили включают обессахаренные классы .
8.2
  • Переписывание правил R8: D8 и R8 могут преобразовать понятные человеку правила базового профиля и профиля запуска, чтобы полностью охватить все правила, необходимые для оптимизации производительности приложения. Увеличивает охват методов базового профиля примерно на 30% и повышает производительность приложения примерно на 15%.
  • Профили запуска: создайте этот новый тип базового профиля для определения структуры кода в DEX. Увеличивает производительность запуска примерно на 15% или значительно больше для крупных приложений.
8.0 Минимальная рекомендуемая версия: используйте плагин Baseline Profile Gradle для генерации базовых профилей с помощью одной задачи Gradle.
  • Полная поддержка каталогов исходных наборов (модули приложений): объявляйте несколько исходных файлов Baseline Profile и используйте каталоги с поддержкой вариантов, например 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 9 (уровень API 28) и выше и хорошо масштабируются только для приложений с достаточно большой базой пользователей.

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

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

Android-версия Метод компиляции Оптимизационный подход
от 5 до 6 (уровень API от 21 до 23) Полный АОТ Все приложение оптимизируется во время установки, что приводит к увеличению времени ожидания перед использованием приложения, увеличению использования оперативной памяти и дискового пространства, а также увеличению времени загрузки кода с диска, что потенциально увеличивает время холодного запуска.
от 7 до 8.1 (уровень API от 24 до 27) Частичный АОТ (базовый профиль) Базовые профили устанавливаются с помощью 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 — генерирует базовые профили только для сборки типа release. Эта проблема была исправлена в AGP 8.1.

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

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

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

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

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