Сбор показателей макробенчмарка

Метрики — это основной тип информации, извлекаемой из ваших бенчмарков. Они передаются в функцию measureRepeated в виде List , что позволяет указывать несколько измеряемых метрик одновременно. Для запуска бенчмарка требуется как минимум один тип метрики.

Приведенный ниже фрагмент кода позволяет получить метрики времени отрисовки кадров и пользовательских разделов трассировки для интерфейса отложенной компоновки Jetpack Compose:

@OptIn(ExperimentalMetricApi::class)
    @Test
    fun scrollComposeList() {
        benchmarkRule.measureRepeated(
            // [START_EXCLUDE]
            packageName = TARGET_PACKAGE,
            metrics = listOf(
                FrameTimingMetric(),
                // Measure power usage. This is supported on Pixel 6 and later.
                PowerMetric(PowerMetric.Type.Power(
                    mapOf(
                        PowerCategory.CPU to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.DISPLAY to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.GPU to PowerCategoryDisplayLevel.TOTAL,
                        PowerCategory.NETWORK to PowerCategoryDisplayLevel.TOTAL,
                    )
                )),
                // Measure custom trace sections by name EntryRow (which is added to the EntryRow composable).
                // Mode.Sum measures combined duration and also how many times it occurred in the trace.
                // This way, you can estimate whether a composable recomposes more than it should.
                TraceSectionMetric("EntryRowCustomTrace", TraceSectionMetric.Mode.Sum),
                // This trace section takes into account the SQL wildcard character %,
                // which can find trace sections without the full name.
                // This way, you can measure composables produced by the composition tracing
                // and measure how long they took and how many times they recomposed.
                // WARNING: This metric only shows results when running with composition tracing, otherwise it won't be visible in the outputs.
                TraceSectionMetric("%EntryRow%", TraceSectionMetric.Mode.Sum),
            ),
            // Try switching to different compilation modes to see the effect
            // it has on frame timing metrics.
            compilationMode = CompilationMode.None(),
            startupMode = StartupMode.WARM, // restarts activity each iteration
            iterations = DEFAULT_ITERATIONS,
            // [END_EXCLUDE]
            setupBlock = {
                uiAutomator {
                    // Before starting to measure, navigate to the UI to be measured.
                    startIntent(Intent("$packageName.COMPOSE_ACTIVITY"))
                }
            }
        ) {
            uiAutomator {
                onElement { isScrollable }.fling(Direction.DOWN)
            }
        }
    }

В следующем примере EntryRowCustomTrace представляет собой пользовательский раздел трассировки, определенный внутри слоев компонуемых элементов с использованием стандартной обертки блока трассировки Kotlin trace(sectionName) { ... } . Чтобы предоставить данные для TraceSectionMetric , необходимо обернуть целевые компоненты пользовательского интерфейса в кодовой базе вашего приложения стандартной оберткой блока trace среды выполнения Jetpack:

@Composable
private fun EntryRow(entry: Entry, modifier: Modifier = Modifier) = trace("EntryRowCustomTrace") {
    Card(modifier = modifier) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            Text(
                text = entry.contents,
                modifier = Modifier
                    .padding(16.dp)
                    .wrapContentSize()
            )

            Spacer(modifier = Modifier.weight(1f))

            Checkbox(
                checked = false,
                onCheckedChange = {},
                modifier = Modifier.padding(16.dp)
            )
        }
    }
}

Результаты бенчмарка выводятся непосредственно на вкладку «Бенчмарк» в Android Studio, как показано на рисунке 1. Если определено несколько метрик, все вычисленные для них данные объединяются в окне сводки.

Результаты функций TraceSectionMetric и FrameTimingMetric.
Рисунок 1. Совместные результаты работы консоли с использованием TraceSectionMetric и FrameTimingMetric для современного макета Compose.

Ниже подробно описаны метрики StartupTimingMetric , FrameTimingMetric , TraceSectionMetric и PowerMetric . Полный список доступных метрик для бенчмаркинга см. в подклассах Metric в справочнике API.

StartupTimingMetric

StartupTimingMetric фиксирует метрики времени запуска приложения со следующими значениями:

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

StartupTimingMetric выводит минимальное, медианное и максимальное значения времени запуска. Для оценки улучшения времени запуска всегда следует ориентироваться на медианные значения, поскольку они дают наилучшую оценку типичного времени запуска для пользователя.

В архитектуре, ориентированной на Compose, не пытайтесь вызывать activity.reportFullyDrawn вручную. Вместо этого используйте безопасные для Compose асинхронные утилиты ReportDrawn , ReportDrawnWhen или ReportDrawnAfter внутри ваших экранных компонентов, чтобы автоматически сообщать Macrobenchmark о завершении отрисовки асинхронных сетевых данных или сложных состояний пользовательского интерфейса.

Для получения дополнительной информации об анализе и оптимизации производительности инициализации см. раздел «Время запуска приложения» .

FrameTimingMetric

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

  • frameOverrunMs : время, на которое данный кадр не достигает установленного срока. Положительные числа указывают на пропущенный кадр, сопровождающийся видимыми рывками или заиканиями. Отрицательные числа указывают на то, насколько быстрее кадр завершился относительно аппаратного предела подсистемы. Примечание: этот показатель доступен только в Android 12 (уровень API 31) и более поздних версиях.
  • frameDurationCpuMs : время, в течение которого кадр активно обрабатывался на ЦП как в основном потоке пользовательского интерфейса приложения, так и в RenderThread Compose.

Данные измерения собраны в виде распределения по 50-му, 90-му, 95-му и 99-му процентилям:

frameDurationCpuMs P50 3.5, P90 6.0, P95 6.4, P99 11.0
frameOverrunMs P50 -11.6, P90 -7.2, P95 -7.1, P99 -1.2

При оптимизации иерархий компоновки Jetpack Compose обратите внимание на кадры с наихудшими показателями производительности (границы P95 и P99). Если frameOverrunMs резко возрастает до положительных целых чисел на высоких процентилях, это указывает на то, что перекомпоновка замедляет основной поток во время анимации с интенсивной прокруткой.

Для получения более подробной информации о выявлении и устранении проблем с медленными кадрами см. раздел «Производительность Jetpack Compose» .

TraceSectionMetric

TraceSectionMetric фиксирует количество повторений определенного участка трассировки и абсолютное время его выполнения. Для отслеживания времени он выводит минимальное, медианное и максимальное значения в миллисекундах. Целевой участок трассировки определяется либо вызовом функции trace(sectionName) , либо границами блоков нижнего уровня между Trace.beginSection(sectionName) и Trace.endSection() или их асинхронными вариантами.

EntryRowCustomTraceCount min 20.0, median 28.0, max 50.0
EntryRowCustomTraceSumMs min 34.9, median 44.4, max 66.6

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

При работе с трассировкой выполнения Jetpack Compose Runtime Tracing вы можете отображать отдельные компонуемые функции в графах трассировки системы без написания оберток трассировки вручную, включив трассировку композиции .

Хотя добавление зависимости androidx.compose.runtime:runtime-tracing к целевому приложению достаточно для трассировки с помощью ручного профилировщика, программный захват этих трассировок в рамках запуска Macrobenchmark требует дополнительной настройки в модуле бенчмарка.

Полные инструкции по настройке см. в разделе «Захват трассировки с помощью Jetpack Macrobenchmark» .

PowerMetric

PowerMetric фиксирует изменение мощности или энергии на протяжении всего выполнения теста Macrobenchmark. Каждая выбранная категория разбивается на измеримые компоненты оборудования, а невыбранные категории группируются в категорию «невыбранные».

Требования к оборудованию : Эти показатели измеряют потребление ресурсов в масштабах всей системы, а не по отдельным приложениям. Следовательно, сбор данных ограничен физическими устройствами Google Pixel 6, Pixel 6 Pro и более новыми моделями.

Данный показатель выдает два результата для каждой категории:

  • power<category>Uw : количество потребляемой мощности за время проведения теста в этой категории (измеряется в микроваттах).
  • energy<category>Uws : общее количество энергии, переданное за единицу времени в течение вашего теста в этой категории (измеряется в микроватт-секундах).

В число категорий входят следующие:

  • CPU
  • DISPLAY
  • GPU
  • GPS
  • MEMORY
  • MACHINE_LEARNING
  • NETWORK
  • UNCATEGORIZED

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

powerCategoryCpuUw min 300.2, median 346.1, max 519.6
powerCategoryDisplayUw min 319.8, median 325.8, max 329.7
powerCategoryGpuUw min 18.8, median 23.3, max 36.9
powerCategoryNetworkUw min 97.3, median 123.3, max 681.3
powerTotalUw min 1234.8, median 1316.6, max 2112.4
powerUnselectedUw       min  483.3,  median  512.6,  max  561.7

Анализ основных подсистем

PowerMetric фиксирует изменение мощности или энергии на протяжении всего теста для указанных категорий мощности. Каждая выбранная вами категория разбивается на измеримые подкомпоненты, а невыбранные категории добавляются к показателю «невыбранные».

Выходные данные терминала соответствуют запрошенной вами конфигурации:

  • powerCategoryCpuUw : Количество энергии, потребляемой процессором в течение всего теста.
  • powerCategoryGpuUw : Количество энергии, потребляемой графическим процессором в течение всего теста.
  • powerUnselectedUw : Суммарная потребляемая мощность всех доступных категорий оборудования, которые не были явно запрошены в вашей карте инициализации.

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

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

Просмотры контента

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}