Pour apprendre à utiliser la bibliothèque Microbenchmark en apportant des modifications au code de votre application, consultez la section Démarrage rapide. Pour savoir comment effectuer une configuration complète avec des modifications plus complexes de votre codebase, consultez la section Configuration complète du projet.
Démarrage rapide
Cette section explique comment tester l'analyse comparative et exécuter des mesures ponctuelles sans avoir à déplacer le code dans des modules. Pour obtenir des résultats de performances précis, ces étapes impliquent la désactivation du débogage dans votre application. Vous devez donc les conserver dans une copie de travail locale sans effectuer de commit des modifications dans votre système de contrôle des sources.
Pour effectuer une analyse comparative ponctuelle, procédez comme suit :
Ajoutez la bibliothèque au fichier
build.gradle
oubuild.gradle.kts
de votre module :Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
Groovy
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
Utiliser une dépendance
implementation
au lieu d'une dépendanceandroidTestImplementation
la dépendance. Si vous utilisezandroidTestImplementation
, les analyses comparatives ne parviennent pas s'exécuter, car le fichier manifeste de la bibliothèque n'est pas fusionné avec l'application fichier manifeste.Mettez à jour le type de compilation
debug
pour qu'il ne soit pas débogable :Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Groovy
android { ... buildTypes { debug { debuggable false } } }
Remplacez
testInstrumentationRunner
parAndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Groovy
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Ajoutez une instance de
BenchmarkRule
dans un fichier de test du répertoireandroidTest
pour ajouter votre benchmark. Pour en savoir plus sur l'écriture des benchmarks, consultez Créer une classe Microbenchmark.L'extrait de code suivant montre comment ajouter un benchmark à un test d'instrumentation :
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() ); } } }
Pour savoir comment écrire un benchmark, passez à l'étape Créer une classe Microbenchmark.
Configuration complète du projet
Pour configurer une analyse comparative régulière plutôt que des analyses comparatives ponctuelles, isolez les benchmarks dans leur propre module. Cela permet de s'assurer que leur configuration, par exemple pour définir debuggable
sur false
, est distincte des tests standards.
Comme Microbenchmark exécute directement votre code, placez le code que vous souhaitez comparer dans un module Gradle distinct et définissez la dépendance sur ce module, comme illustré dans la figure 1.
Pour ajouter un module Gradle, vous pouvez utiliser l'assistant de module dans Android Studio. L'assistant crée un module préconfiguré pour l'analyse comparative, avec un répertoire de benchmark ajouté et debuggable
défini sur false
.
Effectuez un clic droit sur votre projet ou votre module dans le panneau Project (Projet) d'Android Studio, puis cliquez sur New > Module (Nouveau > Module).
Sélectionnez Benchmark dans le volet Templates (Modèles).
Sélectionnez Microbenchmark comme type de module de benchmark.
Saisissez "microbenchmark" comme nom de module.
Cliquez sur Finish (Terminer).
Une fois le module créé, modifiez son fichier build.gradle
ou build.gradle.kts
et ajoutez androidTestImplementation
au module contenant le code à analyser :
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Groovy
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Créer une classe Microbenchmark
Les benchmarks sont des tests d'instrumentation standards. Pour créer un benchmark, utilisez la classe BenchmarkRule
fournie par la bibliothèque. Pour comparer les activités, utilisez ActivityScenario
ou ActivityScenarioRule
. Pour comparer le code de l'interface utilisateur, utilisez @UiThreadTest
.
Le code suivant présente un exemple de benchmark :
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(); } } }
Désactiver la durée pour la configuration
Vous pouvez désactiver la durée pour les sections de code que vous ne souhaitez pas mesurer à l'aide du bloc runWithTimingDisabled{}
. Ces sections représentent généralement du code que vous devez exécuter à chaque itération du benchmark.
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)); }
Essayez de réduire la quantité de travail effectuée dans le bloc measureRepeated
et dans runWithTimingDisabled
. Le bloc measureRepeated
est exécuté plusieurs fois et peut affecter le temps total nécessaire à l'exécution du benchmark. Si vous devez vérifier certains résultats d'un benchmark, vous pouvez revendiquer le dernier résultat au lieu de le faire à chaque itération du benchmark.
Exécuter le benchmark
Dans Android Studio, exécutez votre benchmark comme vous le feriez avec n'importe quel @Test
à l'aide de la gouttière située en regard de votre classe ou méthode de test, comme illustré dans la figure 3.
À partir de la ligne de commande, vous pouvez également exécuter connectedCheck
pour lancer tous les tests du module Gradle spécifié :
./gradlew benchmark:connectedCheck
Ou un seul test :
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
Résultats du benchmark
Après une exécution réussie du microbenchmark, les métriques s'affichent directement dans Android Studio. Un rapport de benchmark complet avec des métriques supplémentaires et des informations sur les appareils est disponible au format JSON.
Les rapports JSON et les traces de profilage sont également copiés automatiquement depuis l'appareil vers l'hôte. Ils sont écrits sur la machine hôte à l'emplacement suivant :
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Par défaut, le rapport JSON est écrit sur le disque de l'appareil, dans le dossier multimédia partagé externe de l'APK de test, qui se trouve généralement à cet emplacement : /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
Erreurs de configuration
La bibliothèque détecte les conditions suivantes pour vous assurer que votre projet et votre environnement sont configurés pour offrir des performances précises :
- Débogable défini sur
false
. - Un appareil physique est en cours d'utilisation (les émulateurs ne sont pas acceptés).
- Les horloges sont verrouillées si l'appareil est en mode root.
- Niveau de batterie suffisant sur l'appareil (au moins 25 %).
Si l'une des vérifications précédentes échoue, le benchmark signale une erreur afin de décourager les mesures inexactes.
Pour supprimer certains types d'erreurs en tant qu'avertissements et les empêcher d'arrêter le benchmark, transmettez le type d'erreur dans une liste d'éléments séparés par une virgule à l'argument d'instrumentation androidx.benchmark.suppressErrors
.
Vous pouvez définir ce paramètre à partir de votre script Gradle, comme dans l'exemple suivant :
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Groovy
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Vous pouvez également supprimer les erreurs à partir de la ligne de commande :
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
La suppression des erreurs permet au benchmark de s'exécuter dans un état mal configuré, et la sortie du benchmark est intentionnellement renommée en ajoutant des préfixes aux noms de test avec l'erreur. Par exemple, l'exécution d'un benchmark débogable avec la suppression incluse dans l'extrait précédent ajoute le préfixe DEBUGGABLE_
aux noms de test.
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé.
- Écrire un macrobenchmark
- Créer des microanalyses comparatives sans Gradle
- Créer des profils de référence {:#creating-profile-rules}