Nous vous recommandons vivement d'automatiser la génération de règles de profil à l'aide de la bibliothèque Jetpack Macrobenchmark afin de réduire les efforts manuels et d'améliorer l'évolutivité générale. Toutefois, vous pouvez créer et mesurer manuellement des règles de profil dans votre application.
Définir des règles de profil manuellement
Vous pouvez définir manuellement des règles de profil dans une application ou un module de bibliothèque en créant un fichier nommé baseline-prof.txt
dans le répertoire src/main
. Il s'agit du même dossier que celui contenant le fichier AndroidManifest.xml
.
Le fichier spécifie une règle par ligne. Chaque règle représente un modèle de correspondance entre les méthodes ou les classes de l'application ou de la bibliothèque qui doivent être optimisées.
La syntaxe de ces règles correspond à un sur-ensemble du format de profil ART (HRF) intelligible lorsque adb shell profman --dump-classes-and-methods
est utilisé. La syntaxe est semblable à la syntaxe des descripteurs et des signatures, mais elle permet d'utiliser des caractères génériques pour simplifier le processus d'écriture des règles.
L'exemple suivant présente quelques règles de profil de référence incluses dans la bibliothèque Jetpack Compose :
HSPLandroidx/compose/runtime/ComposerImpl;->updateValue(Ljava/lang/Object;)V
HSPLandroidx/compose/runtime/ComposerImpl;->updatedNodeCount(I)I
HLandroidx/compose/runtime/ComposerImpl;->validateNodeExpected()V
PLandroidx/compose/runtime/CompositionImpl;->applyChanges()V
HLandroidx/compose/runtime/ComposerKt;->findLocation(Ljava/util/List;I)I
Landroidx/compose/runtime/ComposerImpl;
Vous pouvez essayer de modifier les règles de profil dans cet exemple de projet Compiler Explorer. Notez que Compiler Explorer n'est compatible qu'avec le format de profil ART (HRF) lisible par l'humain. Les caractères génériques ne sont donc pas acceptés.
Syntaxe des règles
Ces règles prennent l'une des formes suivantes pour cibler les méthodes ou les classes :
[FLAGS][CLASS_DESCRIPTOR]->[METHOD_SIGNATURE]
Une règle de classe utilise le format suivant :
[CLASS_DESCRIPTOR]
Consultez le tableau suivant pour obtenir une description détaillée :
Syntaxe | Description |
---|---|
FLAGS |
Représente un ou plusieurs des caractères H , S et P pour indiquer si cette méthode doit être signalée comme Hot , Startup ou Post Startup par rapport au type de démarrage. Une méthode avec l'indicateur H indique qu'il s'agit d'une méthode "Hot", ce qui signifie qu'elle est appelée plusieurs fois pendant la durée de vie de l'application. Une méthode avec l'indicateur S indique qu'il s'agit d'une méthode appelée au démarrage. Une méthode avec l'indicateur P indique qu'il s'agit d'une méthode appelée après le démarrage. Une classe présente dans ce fichier indique qu'elle est utilisée au démarrage et doit être préallouée dans le tas de mémoire pour éviter le coût de chargement de la classe. Le compilateur ART utilise différentes stratégies d'optimisation, telles que la compilation anticipée (ou compilation AOT) de ces méthodes et l'optimisation de la mise en page dans le fichier AOT généré. |
CLASS_DESCRIPTOR |
Descripteur de la classe de méthode ciblée. Par exemple, androidx.compose.runtime.SlotTable contient un descripteur de Landroidx/compose/runtime/SlotTable; . Le préfixe L est ajouté ici au format Dalvik Executable (DEX). |
METHOD_SIGNATURE |
Signature de la méthode, y compris son nom, ses types de paramètres et de retour. Par exemple :// LayoutNode.kt fun isPlaced():Boolean { // ... } sur LayoutNode a la signature isPlaced()Z . |
Ces modèles peuvent avoir des caractères génériques pour qu'une même règle englobe plusieurs méthodes ou classes. Pour obtenir un guide d'écriture avec la syntaxe des règles dans Android Studio, consultez le plug-in Profils de référence Android.
Exemple de règle avec caractères génériques :
HSPLandroidx/compose/ui/layout/**->**(**)**
Types acceptés dans les règles de profil de référence
Les règles de profil de référence sont compatibles avec les types suivants. Pour en savoir plus sur ces types, consultez le format Dalvik Executable (DEX).
Caractère | Type | Description |
---|---|---|
B |
octet | Octet signé |
C |
car. | Point de code de caractères Unicode encodés en UTF-16 |
D |
double | Valeur de double précision à virgule flottante |
F |
float | Valeur de simple précision à virgule flottante |
I |
entier | Nombre entier |
J |
long | Entier long |
S |
court | Signé court |
V |
vide | Vide |
Z |
booléen | Vrai ou faux |
L (nom de classe) |
référence | Instance d'un nom de classe |
De plus, les bibliothèques peuvent définir des règles qui sont empaquetées dans des artefacts d'archive Android (AAR). Lorsque vous créez un APK pour inclure ces artefacts, les règles sont fusionnées (de la même manière que pour le fichier manifeste) et compilées dans un profil ART binaire compact spécifique à l'APK.
ART exploite ce profil lorsque l'APK est utilisé sur les appareils pour une compilation anticipée d'un sous-ensemble spécifique de l'application au moment de l'installation sur Android 9 (niveau d'API 28) ou Android 7 (niveau d'API 24) avec ProfileInstaller
.
Collecter manuellement des profils de référence
Vous pouvez générer manuellement un profil de référence sans configurer la bibliothèque Macrobenchmark et créer des automatisations d'UI pour vos critical user journeys. Bien que l'utilisation des Macrobenchmarks soit recommandée, cela n'est pas toujours possible. Par exemple, si vous utilisez un système de compilation autre que Gradle, vous ne pouvez pas utiliser le plug-in Profil de référence Gradle. Dans ce cas, vous pouvez collecter manuellement les règles du profil de référence. Il est beaucoup plus simple de réaliser cette opération si vous utilisez un appareil ou un émulateur qui exécute le niveau d'API 34 ou supérieur. Bien que cela reste possible avec des niveaux d'API inférieurs, l'opération requiert un accès racine et votre émulateur doit pouvoir exécuter une image AOSP. Pour collecter des règles directement, procédez comme suit :
- Installez une version de votre appli sur un appareil de test. Pour obtenir un profil précis, le type de compilation de l'appli doit être optimisé pour R8 et non débogable.
- Assurez-vous que les profils ne sont pas déjà compilés.
Niveau d'API 34 et supérieur
adb shell cmd package compile -f -m verify $PACKAGE_NAME adb shell pm art clear-app-profiles $PACKAGE_NAME
Niveau d'API 33 et inférieur
adb root adb shell cmd package compile --reset $PACKAGE_NAME
Si votre APK possède une dépendance sur la bibliothèque Jetpack Profile Installer, celle-ci amorce un profil lors du premier lancement de votre APK. Cela peut interférer avec le processus de génération du profil. Désactivez-le à l'aide de la commande suivante :
adb shell am broadcast -a androidx.profileinstaller.action.SKIP_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
- Exécutez l'appli et parcourez manuellement les critical user journeys pour lesquels vous souhaitez collecter un profil.
- Incitez ART à vider les profils. Si votre APK possède une dépendance sur la bibliothèque du programme d'installation de profil Jetpack, utilisez-la pour vider les profils :
adb shell am broadcast -a androidx.profileinstaller.action.SAVE_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver adb shell am force-stop $PACKAGE_NAME
Si vous n'utilisez pas le programme d'installation de profil, videz les profils manuellement sur un émulateur à l'aide de la commande suivante:adb root adb shell killall -s SIGUSR1 $PACKAGE_NAME adb shell am force-stop $PACKAGE_NAME
- Patientez au moins cinq secondes, jusqu'à ce que la génération du profil se termine.
- Convertissez les profils binaires générés au format texte :
Niveau d'API 34 et supérieur
adb shell pm dump-profiles --dump-classes-and-methods $PACKAGE_NAME
Niveau d'API 33 et inférieur
Déterminez si un profil de référence ou un profil actuel a été créé. Les profils de référence se trouvent à l'emplacement suivant :
/data/misc/profiles/ref/$$PACKAGE_NAME/primary.prof
Les profils actuels se trouvent à l'emplacement suivant :
/data/misc/profiles/cur/0/$PACKAGE_NAME/primary.prof
Déterminez l'emplacement de l'APK :
adb root adb shell pm path $PACKAGE_NAME
Effectuez la conversion :
adb root adb shell profman --dump-classes-and-methods --profile-file=$PROFILE_PATH --apk=$APK_PATH > /data/misc/profman/$PACKAGE_NAME-primary.prof.txt
- Utilisez
adb
pour récupérer le profil vidé de l'appareil :adb pull /data/misc/profman/$PACKAGE_NAME-primary.prof.txt PATH_TO_APP_MODULE/src/main/
Les règles de profil générées sont alors extraites et installées dans le module de votre appli. La prochaine fois que vous compilerez l'appli, le profil de référence sera inclus. Vérifiez cela en suivant la procédure décrite dans la section Problèmes d'installation.
Mesurer manuellement les améliorations des applis
Nous vous recommandons fortement de mesurer les améliorations d'applications en procédant à une analyse comparative. Toutefois, si vous souhaitez mesurer les améliorations manuellement, vous pouvez commencer par mesurer le démarrage de l'application non optimisé à titre de référence.
PACKAGE_NAME=com.example.app
# Force Stop App adb shell am force-stop $PACKAGE_NAME # Reset compiled state adb shell cmd package compile --reset $PACKAGE_NAME
# Measure App startup # This corresponds to `Time to initial display` metric. adb shell am start-activity -W -n $PACKAGE_NAME/.ExampleActivity \ | grep "TotalTime"
Ensuite, téléchargez indépendamment le profil de référence.
# Unzip the Release APK first. unzip release.apk
# Create a ZIP archive. # The name should match the name of the APK. # Copy `baseline.prof{m}` and rename it `primary.prof{m}`. cp assets/dexopt/baseline.prof primary.prof cp assets/dexopt/baseline.profm primary.profm
# Create an archive. zip -r release.dm primary.prof primary.profm
# Confirm that release.dm only contains the two profile files: unzip -l release.dm # Archive: release.dm # Length Date Time Name # --------- ---------- ----- ---- # 3885 1980-12-31 17:01 primary.prof # 1024 1980-12-31 17:01 primary.profm # --------- ------- # 2 files
# Install APK + Profile together. adb install-multiple release.apk release.dm
Pour vérifier que le package a été optimisé à l'installation, exécutez la commande suivante :
# Check dexopt state.
adb shell dumpsys package dexopt | grep -A 1 $PACKAGE_NAME
La sortie doit indiquer que le package est compilé :
[com.example.app]
path: /data/app/~~YvNxUxuP2e5xA6EGtM5i9A==/com.example.app-zQ0tkJN8tDrEZXTlrDUSBg==/base.apk
arm64: [status=speed-profile] [reason=install-dm]
Vous pouvez maintenant mesurer les performances de démarrage de l'application comme vous le faisiez auparavant, mais sans réinitialiser l'état compilé. Veillez à ne pas réinitialiser l'état compilé pour le package.
# Force stop app adb shell am force-stop $PACKAGE_NAME
# Measure app startup adb shell am start-activity -W -n $PACKAGE_NAME/.ExampleActivity \ | grep "TotalTime"
Profils de référence et profgen
Cette section décrit le rôle de l'outil profgen lors de la création d'une version binaire compacte d'un profil de référence.
Profgen-cli facilite la compilation de profils, l'introspection et la transpilation de profils ART, afin qu'ils puissent être installés sur des appareils Android, quelle que soit la version du SDK cible.
Profgen-cli est une CLI qui compile le HRF d'un profil de référence dans son format compilé. La CLI est également fournie dans le dépôt cmdline-tools
avec le SDK Android.
Ces fonctionnalités sont disponibles dans la branche studio-main
:
➜ ../cmdline-tools/latest/bin
apkanalyzer
avdmanager
lint
profgen
retrace
screenshot2
sdkmanager
Créer des profils binaires compacts avec Profgen-cli
Les commandes disponibles avec Profgen-cli sont bin
, validate
et dumpProfile
. Pour afficher les commandes disponibles, utilisez profgen --help
:
➜ profgen --help
Usage: profgen options_list
Subcommands:
bin - Generate Binary Profile
validate - Validate Profile
dumpProfile - Dump a binary profile to a HRF
Options:
--help, -h -> Usage info
Utilisez la commande bin
pour générer le profil binaire compact. Voici un exemple d'appel :
profgen bin ./baseline-prof.txt \
--apk ./release.apk \
--map ./obfuscation-map.txt \
--profile-format v0_1_0_p \
--output ./baseline.prof \
Pour afficher les options disponibles, utilisez profgen bin options_list
:
Usage: profgen bin options_list
Arguments:
profile -> File path to Human Readable profile { String }
Options:
--apk, -a -> File path to apk (always required) { String }
--output, -o -> File path to generated binary profile (always required)
--map, -m -> File path to name obfuscation map { String }
--output-meta, -om -> File path to generated metadata output { String }
--profile-format, -pf [V0_1_0_P] -> The ART profile format version
{ Value should be one of [
v0_1_5_s, v0_1_0_p, v0_0_9_omr1, v0_0_5_o, v0_0_1_n
]
}
--help, -h -> Usage info
Le premier argument représente le chemin d'accès au HRF baseline-prof.txt
.
Profgen-cli a également besoin du chemin d'accès au build de l'APK et d'un mappage d'obscurcissement qui permet d'obscurcir l'APK lorsque vous utilisez R8 ou ProGuard. De cette façon, profgen
peut traduire les symboles sources du HRF en noms obscurcis correspondants lors de la création du profil compilé.
Étant donné que les formats de profil ART ne sont pas compatibles avec les versions futures ou antérieures, fournissez un format de profil permettant à profgen
de regrouper les métadonnées de profil (profm
) que vous pouvez utiliser pour transcoder un format de profil ART dans un autre format lorsque c'est obligatoire.
Formats de profil et versions de la plate-forme
Les options suivantes sont disponibles lorsque vous choisissez un format de profil :
Format du profil | Version de la plate-forme | Niveau d'API |
---|---|---|
v0_1_5_s | Android S+ | 31 ou + |
v0_1_0_p | Android P, Q et R | 28-30 |
v0_0_9_omr1 | Android O MR1 | 27 |
v0_0_5_o | Android O | 26 |
v0_0_1_n | Android N | 24-25 |
Copiez les fichiers de sortie baseline.prof
et baseline.profm
dans le dossier assets
ou dexopt
de l'APK.
Cartes d'obscurcissement
Vous ne devez fournir la carte d'obscurcissement que si le HRF utilise des symboles sources. Si la HRF est générée à partir d'un build déjà obscurci et qu'aucun mappage n'est nécessaire, vous pouvez ignorer cette option et copier les sorties dans le dossier assets
ou dexopt
.
Installation classique des profils de référence
Les profils de référence sont traditionnellement distribués sur un appareil de deux manières.
Utiliser install-multiple
avec DexMetadata
Sur les appareils exécutant l'API 28 ou une version ultérieure, le client Play télécharge l'APK et la charge utile DexMetadata (DM) pour l'installation d'une version d'APK. La DM contient les informations de profil transmises au gestionnaire de paquets de l'appareil.
L'APK et la DM sont installés dans le cadre d'une seule session d'installation, par exemple à l'aide de l'instruction suivante :
adb install-multiple base.apk base.dm
Jetpack ProfileInstaller
Sur les appareils exécutant le niveau d'API 29 ou ultérieur, la bibliothèque Jetpack ProfileInstaller fournit un mécanisme alternatif pour installer un profil empaqueté dans assets
ou dexopt
après l'installation de l'APK sur l'appareil. ProfileInstaller
est appelé par ProfileInstallReceiver
ou directement par l'application.
La bibliothèque ProfileInstaller transcode le profil en fonction de la version du SDK de l'appareil cible et le copie dans le répertoire cur
de l'appareil (un répertoire de préproduction spécifique au package pour les profils ART sur l'appareil).
Une fois l'appareil inactif, le profil est récupéré par un processus appelé bg-dexopt
sur l'appareil.
Télécharger un profil de référence indépendamment
Cette section explique comment installer un profil de référence à partir d'un APK.
Diffuser avec androidx.profileinstaller
Sur les appareils exécutant l'API 24 ou une version ultérieure, vous pouvez diffuser une commande pour installer le profil :
# Broadcast the install profile command - moves binary profile from assets
# to a location where ART uses it for the next compile.
# When successful, the following command prints "1":
adb shell am broadcast \
-a androidx.profileinstaller.action.INSTALL_PROFILE \
<pkg>/androidx.profileinstaller.ProfileInstallReceiver
# Kill the process
am force-stop <pkg>
# Compile the package based on profile
adb shell cmd package compile -f -m speed-profile <pkg>
ProfileInstaller n'est pas présent dans la plupart des APK avec des profils de référence, qui sont inclus dans environ 77 000 applications sur 450 000 dans Google Play, bien qu'il soit présent dans chaque APK utilisant Compose. Les bibliothèques peuvent fournir des profils sans déclarer de dépendances sur ProfileInstaller. L'ajout d'une dépendance dans chaque bibliothèque avec un profil s'applique à partir de Jetpack.
Utiliser install-multiple
avec profgen ou DexMetaData
Sur les appareils exécutant l'API 28 ou une version ultérieure, vous pouvez télécharger un profil de référence indépendamment, sans avoir à accéder à la bibliothèque ProfileInstaller.
Pour ce faire, utilisez Profgen-cli :
profgen extractProfile \
--apk app-release.apk \
--output-dex-metadata app-release.dm \
--profile-format V0_1_5_S # Select based on device and the preceding table.
# Install APK and the profile together
adb install-multiple appname-release.apk appname-release.dm
Pour prendre en charge les APK divisés, exécutez les étapes précédentes du profil d'extraction une fois par APK. Au moment de l'installation, transmettez chaque APK et le fichier .dm
associé, en vous assurant que les noms de l'APK et de .dm
correspondent :
adb install-multiple appname-base.apk appname-base.dm \
appname-split1.apk appname-split1.dm
Validation
Pour vérifier que le profil est correctement installé, suivez la procédure décrite dans Mesurer manuellement les améliorations d'une application.
Vider le contenu d'un profil binaire
Pour introduire le contenu d'une version binaire compacte d'un profil de référence, utilisez l'option dumpProfile
de Profgen-cli :
Usage: profgen dumpProfile options_list
Options:
--profile, -p -> File path to the binary profile (always required)
--apk, -a -> File path to apk (always required) { String }
--map, -m -> File path to name obfuscation map { String }
--strict, -s [true] -> Strict mode
--output, -o -> File path for the HRF (always required) { String }
--help, -h -> Usage info
dumpProfile
a besoin de l'APK, car la représentation binaire compacte ne stocke que des décalages DEX. Par conséquent, il a besoin de reconstruire les noms des classes et des méthodes.
Le mode strict est activé par défaut. Il effectue une vérification de compatibilité du profil avec les fichiers DEX de l'APK. Si vous essayez de déboguer des profils générés par un autre outil, vous pouvez obtenir des échecs de compatibilité qui vous empêchent de procéder à une analyse. Dans ce cas, vous pouvez désactiver le mode strict avec --strict false
. Toutefois, dans la plupart des cas, vous devez laisser le mode strict activé.
Un plan d'obscurcissement est facultatif. Lorsqu'il est fourni, il permet de remapper les symboles obscurcis vers leurs versions lisibles par l'humain pour faciliter leur utilisation.
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé.
- Bonnes pratiques pour les performances de SQLite
- Profils de référence {:#baseline-profiles}
- Wakelocks partiels figés