Чтобы узнать, как использовать библиотеку Microbenchmark, добавляя изменения в код приложения, ознакомьтесь с разделом Быстрый старт. Чтобы узнать, как выполнить полную настройку с более сложными изменениями в базе кода, ознакомьтесь с разделом Полная настройка проекта.
Краткое руководство
В этом разделе показано, как попробовать бенчмаркинг и запустить разовые измерения, не перемещая код в модули. Чтобы получить точные результаты, отключите отладку в приложении. Для этого сохраните локальную рабочую копию, не внося изменения в систему управления версиями.
Чтобы выполнить однократное сравнение, сделайте следующее:
Добавьте библиотеку в файл
build.gradleилиbuild.gradle.ktsмодуля:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
Яркий
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
Используйте зависимость
implementationвместоandroidTestImplementation. Если вы используетеandroidTestImplementation, тесты не будут выполняться, поскольку манифест библиотеки не объединен с манифестом приложения.Обновите тип сборки
debug, чтобы она не была отладочной:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Яркий
android { ... buildTypes { debug { debuggable false } } }
Измените
testInstrumentationRunnerнаAndroidBenchmarkRunner:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Яркий
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Добавьте экземпляр
BenchmarkRuleв тестовый файл в каталогеandroidTest, чтобы добавить свой тест производительности. Подробнее о том, как создать класс Microbenchmark…В следующем фрагменте кода показано, как добавить тест производительности в инструментальный тест:
Kotlin
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
Java
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { BenchmarkRuleKt.measureRepeated( (Function1<BenchmarkRule.Scope, Unit>) scope -> doSomeWork() ); } } }
Чтобы узнать, как написать тест, перейдите к разделу Создание класса Microbenchmark.
Полная настройка проекта
Чтобы настроить регулярное тестирование производительности, а не однократное, выделите тесты в отдельный модуль. Это позволяет отделить их конфигурацию, например настройку debuggable со значением false, от обычных тестов.
Поскольку Microbenchmark запускает ваш код напрямую, поместите код, который вы хотите протестировать, в отдельный модуль Gradle и установите зависимость от этого модуля, как показано на рисунке 1.
:app, :microbenchmark и :benchmarkable, которая позволяет Microbenchmarks тестировать код в модуле :benchmarkable.Чтобы добавить новый модуль Gradle, используйте мастер модулей в Android Studio. Мастер создаст модуль, предварительно настроенный для тестирования, с добавленным каталогом тестов и параметром debuggable, установленным в значение false.
На панели Project (Проект) в Android Studio нажмите правой кнопкой мыши на проект или модуль и выберите New > Module (Создать > Модуль).
На панели Шаблоны выберите Контрольный показатель.
В качестве типа модуля выберите Microbenchmark.
Введите "microbenchmark" в качестве названия модуля.
Нажмите Готово.
После создания модуля измените его файл build.gradle или build.gradle.kts и добавьте androidTestImplementation в модуль, содержащий код для тестирования:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Яркий
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Создание класса Microbenchmark
Тесты производительности – это стандартные инструментальные тесты. Чтобы создать тест, используйте класс BenchmarkRule, предоставляемый библиотекой. Для сравнения действий используйте ActivityScenario или ActivityScenarioRule. Для тестирования кода пользовательского интерфейса используйте @UiThreadTest.
Ниже приведен пример кода для теста производительности.
Kotlin
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
Java
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { final BenchmarkState state = benchmarkRule.getState(); while (state.keepRunning()) { doSomeWork(); } } }
Отключить таймер для настройки
Вы можете отключить отслеживание времени для разделов кода, которые не хотите измерять, с помощью блока runWithTimingDisabled{}. Обычно это код, который нужно выполнять на каждой итерации теста.
Kotlin
// using random with the same seed, so that it generates the same data every run private val random = Random(0) // create the array once and just copy it in benchmarks private val unsorted = IntArray(10_000) { random.nextInt() } @Test fun benchmark_quickSort() { // ... benchmarkRule.measureRepeated { // copy the array with timing disabled to measure only the algorithm itself listToSort = runWithTimingDisabled { unsorted.copyOf() } // sort the array in place and measure how long it takes SortingAlgorithms.quickSort(listToSort) } // assert only once not to add overhead to the benchmarks assertTrue(listToSort.isSorted) }
Java
private final int[] unsorted = new int[10000]; public SampleBenchmark() { // Use random with the same seed, so that it generates the same data every // run. Random random = new Random(0); // Create the array once and copy it in benchmarks. Arrays.setAll(unsorted, (index) -> random.nextInt()); } @Test public void benchmark_quickSort() { final BenchmarkState state = benchmarkRule.getState(); int[] listToSort = new int[0]; while (state.keepRunning()) { // Copy the array with timing disabled to measure only the algorithm // itself. state.pauseTiming(); listToSort = Arrays.copyOf(unsorted, 10000); state.resumeTiming(); // Sort the array in place and measure how long it takes. SortingAlgorithms.quickSort(listToSort); } // Assert only once, not to add overhead to the benchmarks. assertTrue(SortingAlgorithmsKt.isSorted(listToSort)); }
Постарайтесь минимизировать объем работы, выполняемой внутри блока measureRepeated и внутри runWithTimingDisabled. Блок measureRepeated выполняется несколько раз, и это может повлиять на общее время, необходимое для выполнения теста. Если вам нужно проверить некоторые результаты теста, вы можете подтвердить последний результат, а не делать это на каждой итерации теста.
Как запустить тест
Запустите тест производительности в Android Studio так же, как и любой другой тест @Test, используя действие на полях рядом с тестовым классом или методом, как показано на рисунке 3.
Вы также можете запустить все тесты из указанного модуля Gradle, выполнив в командной строке команду connectedCheck.
./gradlew benchmark:connectedCheckили один тест:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWorkРезультат сравнения
После успешного запуска Microbenchmark показатели отображаются непосредственно в Android Studio, а полный отчет о тестировании с дополнительными показателями и информацией об устройстве доступен в формате JSON.
Отчеты JSON и трассировки профилирования также автоматически копируются с устройства на хост. Они записываются на хост-компьютере в следующем расположении:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
По умолчанию отчет в формате JSON записывается на диск на устройстве в общую папку тестового APK-файла, которая обычно находится по адресу /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json.
Ошибки конфигурации
Библиотека обнаруживает следующие условия, чтобы убедиться, что ваш проект и среда настроены для точной оценки производительности:
- Для атрибута debuggable задано значение
false. - Используется физическое устройство (эмуляторы не поддерживаются).
- Если на устройстве есть root-доступ, частота заблокирована.
- Уровень заряда батареи на устройстве не менее 25%.
Если какая-либо из предыдущих проверок не удалась, тест сообщает об ошибке, чтобы предотвратить неточные измерения.
Чтобы подавить определенные типы ошибок как предупреждения и предотвратить остановку теста, передайте тип ошибки в виде списка, разделенного запятыми, в аргумент инструментирования androidx.benchmark.suppressErrors.
Это можно сделать в скрипте Gradle, как показано в примере ниже.
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Яркий
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Вы также можете подавить ошибки из командной строки:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
Подавление ошибок позволяет запустить тест производительности в неправильно настроенном состоянии, а выходные данные теста намеренно переименовываются путем добавления ошибки к именам тестов. Например, при запуске отладочного теста с подавлением в предыдущем фрагменте к именам тестов добавляется DEBUGGABLE_.
Рекомендуем
- Примечание. Текст ссылки показывается, когда JavaScript отключен.
- Как написать макротест
- Как создавать микротесты без Gradle
- Как создать профиль базовой конфигурации {:#creating-profile-rules}