Vous pouvez exécuter des benchmarks dans l'intégration continue (CI) pour suivre les performances au fil du temps et identifier les régressions (ou les améliorations) de performances avant même le lancement de votre application. Cette page fournit des informations de base sur le benchmark dans la CI.
Avant de commencer à utiliser l'analyse comparative dans la CI, tenez compte des différences entre la capture et l'évaluation des résultats et les tests standards.
Résultats flous
Bien que les benchmarks soient des tests instrumentés, les résultats ne se traduisent pas simplement par une réussite ou un échec. Les benchmarks fournissent des mesures temporelles pour l'appareil sur lequel elles s'exécutent. La représentation graphique des résultats au fil du temps vous permet de surveiller les modifications et d'observer le bruit dans le système de mesure.
Utiliser de vrais appareils
Exécutez des benchmarks sur des appareils Android physiques. Bien qu'ils puissent s'exécuter sur des émulateurs, nous vous le déconseillons vivement, car cela ne représente pas une expérience utilisateur réaliste. Cette approche fournit plutôt des chiffres liés au système d'exploitation hôte et aux fonctionnalités matérielles. Envisagez d'utiliser des appareils réels ou un service qui vous permet d'exécuter des tests sur des appareils réels, tels que Firebase Test Lab.
Exécuter les benchmarks
L'exécution des benchmarks dans votre pipeline CI peut être différente de l'exécution locale à partir d'Android Studio. En local, vous exécutez généralement les tests d'intégration Android avec une tâche connectedCheck
Gradle. Cette tâche crée automatiquement votre APK et votre APK de test, puis exécute les tests sur le ou les appareils connectés au serveur CI. Lors de l'exécution dans la CI, ce flux doit généralement être divisé en plusieurs phases.
Créer
Pour la bibliothèque Microbenchmark, exécutez la tâche Gradle assemble[VariantName]AndroidTest
, qui crée votre APK de test contenant à la fois le code de votre application et votre code testé.
La bibliothèque Macrobenchmark nécessite également de créer votre APK cible et de tester l'APK séparément. Exécutez donc les tâches Gradle :app:assemble[VariantName]
et :macrobenchmark:assemble[VariantName]
.
Installer et exécuter
Ces étapes se font généralement sans qu'il soit nécessaire d'exécuter des tâches Gradle. Notez qu'elles peuvent être extraites selon que vous utilisez ou non un service qui vous permet d'exécuter des tests sur des appareils réels.
Pour l'installation, utilisez la commande adb install
et spécifiez l'APK test (ou l'APK cible).
Exécutez la commande instrument adb shell am
pour exécuter tous les benchmarks :
adb shell am instrument -w com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Lorsque vous utilisez la bibliothèque Macrobenchmark, utilisez l'androidx.test.runner.AndroidJUnitRunner
standard en tant qu'exécuteur d'instrumentation.
Vous pouvez transmettre les mêmes arguments d'instrumentation que dans la configuration Gradle à l'aide de l'argument -e
. Pour toutes les options d'arguments d'instrumentation, consultez les sections Arguments d'instrumentation de Microbenchmark et Ajouter des arguments d'instrumentation pour Macrobenchmark.
Par exemple, vous pouvez définir l'argument dryRunMode
pour exécuter des microbenchmarks dans votre processus de validation des demandes d'extraction. Lorsque cet indicateur est activé, les microbenchmarks ne s'exécutent qu'en boucle simple, ce qui permet de vérifier qu'ils fonctionnent correctement, sans prendre trop de temps.
adb shell am instrument -w -e "androidx.benchmark.dryRunMode.enable" "true" com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Pour en savoir plus sur l'exécution de tests d'instrumentation à partir de la ligne de commande, consultez Exécuter des tests avec ADB.
Verrouiller des horloges
Le plug-in Gradle de Microbenchmark fournit la commande ./gradlew lockClocks
permettant de verrouiller les horloges de processeur d'un appareil en mode root. Cela est utile pour garantir la stabilité lorsque vous avez accès aux appareils en mode root, tels que les builds « userdebug ». Vous pouvez répliquer cela à l'aide du script shell lockClocks.sh
, disponible dans la source de la bibliothèque.
Vous pouvez exécuter le script directement à partir d'un hôte Linux ou Mac, ou le transférer sur l'appareil à l'aide de quelques commandes adb :
adb push path/lockClocks.sh /data/local/tmp/lockClocks.sh adb shell /data/local/tmp/lockClocks.sh adb shell rm /data/local/tmp/lockClocks.sh
Si vous exécutez le script shell directement sur un hôte, il envoie ces commandes à un appareil connecté.
Pour savoir pourquoi il est utile de verrouiller les horloges de processeur, découvrez comment obtenir des benchmarks cohérents.
Recueillir les résultats
Les bibliothèques d'analyse comparative génèrent des mesures au format JSON, ainsi que des traces de profilage vers un répertoire de l'appareil Android après chaque exécution de benchmark. La bibliothèque Macrobenchmark génère plusieurs fichiers de suivi Perfetto : un par itération mesurée de chaque boucle MacrobenchmarkRule.measureRepeated
. Microbenchmark, en revanche, crée un seul fichier de suivi pour toutes les itérations de chaque BenchmarkRule.measureRepeated
. Les fichiers de suivi de profilage sont également générés dans ce même répertoire.
Enregistrer et localiser les fichiers
Si vous exécutez les benchmarks avec Gradle, ces fichiers sont automatiquement copiés sous build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/
dans le répertoire de sortie de votre ordinateur hôte.
Si vous exécutez directement la commande adb
, vous devez extraire les fichiers manuellement. Par défaut, les rapports sont enregistrés sur l'appareil dans le répertoire multimédia de la mémoire de stockage externe de l'application testée. Pour plus de commodité, la bibliothèque affiche le chemin du fichier dans Logcat. Notez que le dossier de sortie peut varier selon la version d'Android sur laquelle les benchmarks s'exécutent.
Benchmark: writing results to /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json
Vous pouvez également configurer l'emplacement où les rapports de benchmark sont enregistrés sur l'appareil à l'aide de l'argument d'instrumentation additionalTestOutputDir
. Ce dossier doit être accessible en écriture par votre application.
adb shell am instrument -w -e additionalTestOutputDir /sdcard/Download/ com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Sur Android 10 (niveau d'API 29) ou version ultérieure, les tests de votre appli s'exécutent par défaut dans un bac à sable de stockage, ce qui empêche votre application d'accéder aux fichiers situés en dehors du répertoire spécifique à l'appli. Pour pouvoir enregistrer dans un répertoire global, tel que /sdcard/Download
, transmettez l'argument d'instrumentation suivant :
-e no-isolated-storage true
Vous devez également autoriser explicitement les anciennes options de stockage dans le fichier manifeste de votre benchmark :
<application android:requestLegacyExternalStorage="true" ... >
Pour en savoir plus, consultez la section Désactiver temporairement l'espace de stockage cloisonné.
Récupérer les fichiers
Pour récupérer les fichiers générés à partir de l'appareil, exécutez la commande adb pull
, qui extrait le fichier spécifié dans le répertoire actuel de votre hôte :
adb pull /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json
Pour récupérer toutes les benchmarkData
d'un dossier spécifié, reportez-vous à l'extrait de code suivant :
# The following command pulls all files ending in -benchmarkData.json from the directory
# hierarchy starting at the root /storage/emulated/0/Android.
adb shell find /sdcard/Download -name "*-benchmarkData.json" | tr -d '\r' | xargs -n1 adb pull
Notez que les fichiers de suivi (.trace
ou .perfetto-trace
) sont enregistrés dans le même dossier que benchmarkData.json
. Vous pouvez donc les collecter de la même manière.
Exemple de données de benchmark
Les bibliothèques de benchmark génèrent des fichiers JSON contenant des informations sur l'appareil d'exécution des benchmarks ainsi que sur les benchmarks réellement exécutés. L'extrait de code suivant représente le fichier JSON généré :
{
"context": {
"build": {
"brand": "google",
"device": "blueline",
"fingerprint": "google/blueline/blueline:12/SP1A.210812.015/7679548:user/release-keys",
"model": "Pixel 3",
"version": {
"sdk": 31
}
},
"cpuCoreCount": 8,
"cpuLocked": false,
"cpuMaxFreqHz": 2803200000,
"memTotalBytes": 3753299968,
"sustainedPerformanceModeEnabled": false
},
"benchmarks": [
{
"name": "startup",
"params": {},
"className": "com.example.macrobenchmark.startup.SampleStartupBenchmark",
"totalRunTimeNs": 4975598256,
"metrics": {
"timeToInitialDisplayMs": {
"minimum": 347.881076,
"maximum": 347.881076,
"median": 347.881076,
"runs": [
347.881076
]
}
},
"sampledMetrics": {},
"warmupIterations": 0,
"repeatIterations": 3,
"thermalThrottleSleepSeconds": 0
}
]
}
Ressources supplémentaires
- Pour en savoir plus sur la détection des régressions de performances, consultez Lutter contre les régressions avec les benchmarks dans la CI.
- Pour savoir comment configurer des actions GitHub avec Firebase Test Lab, consultez Configurer Jetpack Macrobenchmarks pour la CI.
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé.
- Bonnes pratiques pour les performances de SQLite
- Créer et mesurer des profils de référence sans Macrobenchmark
- Wakelocks partiels figés