Membuat dan mengukur Profil Dasar Pengukuran secara manual

Sebaiknya Anda mengotomatiskan pembuatan aturan profil menggunakan library Jetpack Macrobenchmark untuk mengurangi upaya manual dan meningkatkan skalabilitas umum. Namun, Anda dapat membuat dan mengukur aturan profil secara manual di aplikasi.

Menentukan aturan profil secara manual

Anda dapat menentukan aturan profil secara manual di aplikasi atau modul library dengan membuat file bernama baseline-prof.txt yang berada di direktori src/main. Ini adalah folder yang sama yang berisi file AndroidManifest.xml.

File tersebut menentukan satu aturan per baris. Setiap aturan mewakili pola untuk metode atau class yang cocok di aplikasi atau library yang perlu dioptimalkan.

Sintaksis untuk aturan ini adalah superset dari format profil ART yang dapat dibaca manusia (HRF) saat menggunakan adb shell profman --dump-classes-and-methods. Sintaksisnya mirip dengan sintaksis untuk deskripsi dan tanda tangan, tetapi karakter pengganti dapat digunakan untuk menyederhanakan proses penulisan aturan.

Contoh berikut menunjukkan beberapa aturan Profil Dasar Pengukuran yang disertakan dalam library 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;

Anda dapat mencoba mengubah aturan profil di contoh project Compiler Explorer ini. Perhatikan bahwa Compiler Explorer hanya mendukung format profil ART yang dapat dibaca manusia (HRF), sehingga karakter pengganti tidak didukung.

Sintaksis aturan

Aturan ini menggunakan salah satu dari dua bentuk untuk ditarget, yaitu metode atau class:

[FLAGS][CLASS_DESCRIPTOR]->[METHOD_SIGNATURE]

Aturan class menggunakan pola berikut:

[CLASS_DESCRIPTOR]

Lihat tabel berikut untuk deskripsi mendetail:

Sintaksis Deskripsi
FLAGS Mewakili satu atau beberapa karakter H, S, dan P untuk menunjukkan apakah metode ini harus ditandai sebagai Hot, Startup, atau Post Startup terkait dengan jenis startup.

Metode dengan tanda H menunjukkan bahwa metode tersebut "panas", yang berarti metode tersebut akan dipanggil beberapa kali sepanjang waktu penggunaan aplikasi.

Metode dengan tanda S menunjukkan bahwa metode ini dipanggil selama startup.

Metode dengan tanda P menunjukkan bahwa metode ini dipanggil setelah startup.

Class yang ada dalam file ini menunjukkan bahwa class digunakan saat startup dan harus dialokasikan sebelumnya di heap untuk menghindari biaya pemuatan class. Compiler ART menggunakan berbagai strategi pengoptimalan, seperti kompilasi AOT metode ini dan melakukan pengoptimalan tata letak di file AOT yang dihasilkan.
CLASS_DESCRIPTOR Deskripsi untuk class metode yang ditargetkan. Misalnya, androidx.compose.runtime.SlotTable memiliki deskripsi Landroidx/compose/runtime/SlotTable;. L ditambahkan di sini sesuai format Dalvik Executable (DEX).
METHOD_SIGNATURE Tanda tangan metode, termasuk nama, jenis parameter, dan jenis nilai yang ditampilkan dari metode. Contoh:

// LayoutNode.kt

fun isPlaced():Boolean {
// ...
}

di LayoutNode memiliki tanda tangan isPlaced()Z.

Pola ini dapat memiliki karakter pengganti agar memiliki satu aturan yang mencakup beberapa metode atau class. Untuk mendapatkan bantuan terpandu saat menulis dengan sintaksis aturan di Android Studio, lihat plugin Profil Dasar Pengukuran Android.

Contoh aturan karakter pengganti mungkin terlihat seperti ini:

HSPLandroidx/compose/ui/layout/**->**(**)**

Jenis yang didukung dalam aturan Profil Dasar Pengukuran

Aturan Profil Dasar Pengukuran mendukung jenis berikut. Untuk mengetahui detail tentang jenis ini, lihat Format Dalvik Executable (DEX).

Karakter Jenis Deskripsi
B byte Byte bertanda tangan
C karakter Poin kode karakter unicode yang dienkode dalam UTF-16
D ganda Nilai floating point presisi ganda
F float Nilai floating point presisi tunggal
I int Bilangan Bulat
J long Bilangan bulat panjang
S short Bertanda tangan singkat
V void Void
Z boolean Benar atau salah
L (nama class) referensi Instance nama class

Selain itu, library dapat menentukan aturan yang dikemas dalam artefak AAR. Saat Anda membangun APK untuk menyertakan artefak ini, aturan digabungkan—serupa dengan cara penggabungan manifes—dan dikompilasi ke profil ART biner ringkas yang khusus untuk APK.

ART memanfaatkan profil ini jika APK digunakan di perangkat untuk mengompilasi AOT subset aplikasi tertentu pada waktu penginstalan di Android 9 (level API 28), atau Android 7 (level API 24) saat menggunakan ProfileInstaller.

Mengumpulkan Profil Dasar Pengukuran secara manual

Anda dapat membuat Profil Dasar Pengukuran secara manual tanpa menyiapkan library Macrobenchmark dan membuat otomatisasi UI perjalanan penting pengguna. Meskipun kami merekomendasikan penggunaan Macrobenchmark, hal ini mungkin tidak selalu memungkinkan. Misalnya, jika menggunakan sistem build non-Gradle, Anda tidak dapat menggunakan plugin Gradle Profil Dasar Pengukuran. Dalam kasus tersebut, Anda dapat mengumpulkan aturan Profil Dasar Pengukuran secara manual. Hal ini jauh lebih mudah jika Anda menggunakan perangkat atau emulator yang menjalankan API 34 dan yang lebih tinggi. Meskipun masih dapat dilakukan dengan level API yang lebih rendah, tindakan ini memerlukan akses root, dan Anda harus menggunakan emulator yang menjalankan image AOSP. Anda dapat mengumpulkan aturan secara langsung dengan melakukan hal berikut:

  1. Instal versi rilis aplikasi Anda di perangkat pengujian. Jenis build aplikasi harus dioptimalkan R8 dan tidak dapat di-debug untuk profil yang akurat.
  2. Pastikan profil belum dikompilasi.

    API 34 dan yang lebih tinggi

    adb shell cmd package compile -f -m verify $PACKAGE_NAME
    adb shell pm art clear-app-profiles $PACKAGE_NAME

    API 33 dan yang lebih lama

    adb root
    adb shell cmd package compile --reset $PACKAGE_NAME

    Jika APK Anda memiliki dependensi pada library Jetpack Profile Installer, library akan mem-bootstrap profil saat peluncuran pertama APK Anda. Hal ini dapat mengganggu proses pembuatan profil, jadi nonaktifkan dengan perintah berikut:

    adb shell am broadcast -a androidx.profileinstaller.action.SKIP_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
  3. Jalankan aplikasi dan jelajahi perjalanan penting pengguna yang ingin Anda kumpulkan profilnya secara manual.
  4. Minta ART untuk membuang profil. Jika APK Anda memiliki dependensi pada library Jetpack Profile Installer, gunakan library tersebut untuk membuang profil:

    adb shell am broadcast -a androidx.profileinstaller.action.SAVE_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
    adb shell am force-stop $PACKAGE_NAME
    Jika Anda tidak menggunakan Profile Installer, dump profil secara manual di emulator menggunakan perintah berikut:

    adb root
    adb shell killall -s SIGUSR1 $PACKAGE_NAME
    adb shell am force-stop $PACKAGE_NAME
  5. Tunggu minimal lima detik hingga pembuatan profil selesai.
  6. Konversikan profil biner yang dihasilkan menjadi teks:

    API 34 dan yang lebih tinggi

    adb shell pm dump-profiles --dump-classes-and-methods $PACKAGE_NAME

    API 33 dan yang lebih lama

    Tentukan apakah profil referensi atau profil saat ini telah dibuat. Profil referensi berada di lokasi berikut:

    /data/misc/profiles/ref/$$PACKAGE_NAME/primary.prof

    Profil saat ini berada di lokasi berikut:

    /data/misc/profiles/cur/0/$PACKAGE_NAME/primary.prof

    Tentukan lokasi APK:

    adb root
    adb shell pm path $PACKAGE_NAME

    Lakukan konversi:

    adb root
    adb shell profman --dump-classes-and-methods --profile-file=$PROFILE_PATH --apk=$APK_PATH > /data/misc/profman/$PACKAGE_NAME-primary.prof.txt

  7. Gunakan adb untuk mengambil profil yang di-dump dari perangkat:

    adb pull /data/misc/profman/$PACKAGE_NAME-primary.prof.txt PATH_TO_APP_MODULE/src/main/

Tindakan ini akan mengambil aturan profil yang dihasilkan dan menginstalnya ke modul aplikasi Anda. Saat Anda mem-build aplikasi lagi, Profil Dasar Pengukuran akan disertakan. Verifikasi hal ini dengan mengikuti langkah-langkah di bagian Masalah penginstalan.

Mengukur peningkatan aplikasi secara manual

Sebaiknya Anda mengukur peningkatan aplikasi melalui tolok ukur. Namun, jika ingin mengukur peningkatan secara manual, Anda dapat memulai dengan mengukur startup aplikasi yang tidak dioptimalkan untuk referensi.

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"

Selanjutnya, lakukan sideload Profil Dasar Pengukuran.

# 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

Untuk memastikan bahwa paket dioptimalkan saat penginstalan, jalankan perintah berikut:

# Check dexopt state.
adb shell dumpsys package dexopt | grep -A 1 $PACKAGE_NAME

Output harus menyatakan bahwa paket dikompilasi:

[com.example.app]
  path: /data/app/~~YvNxUxuP2e5xA6EGtM5i9A==/com.example.app-zQ0tkJN8tDrEZXTlrDUSBg==/base.apk
  arm64: [status=speed-profile] [reason=install-dm]

Sekarang, Anda dapat mengukur performa startup aplikasi seperti sebelumnya, tetapi tanpa mereset status kompilasi. Pastikan Anda tidak mereset status yang dikompilasi untuk paket.

# 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"

Profil Dasar Pengukuran dan profgen

Bagian ini menjelaskan fungsi alat profgen saat membuat versi biner ringkas dari Profil Dasar Pengukuran.

Profgen-cli membantu kompilasi profil, introspeksi, dan transpilasi profil ART, sehingga dapat diinstal di perangkat Android, apa pun versi SDK targetnya.

Profgen-cli adalah CLI yang mengompilasi HRF Profil Dasar Pengukuran ke format yang dikompilasi. CLI juga dikirim dalam repositori cmdline-tools sebagai bagian dari Android SDK.

Fitur ini tersedia di cabang studio-main:

 ../cmdline-tools/latest/bin
apkanalyzer
avdmanager
lint
profgen
retrace
screenshot2
sdkmanager

Membuat profil biner ringkas dengan Profgen-cli

Perintah yang tersedia dengan Profgen-cli adalah bin, validate, dan dumpProfile. Untuk melihat perintah yang tersedia, gunakan 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

Gunakan perintah bin untuk membuat profil biner ringkas. Berikut adalah contoh pemanggilan:

profgen bin ./baseline-prof.txt \
  --apk ./release.apk \
  --map ./obfuscation-map.txt \
  --profile-format v0_1_0_p \
  --output ./baseline.prof \

Untuk melihat opsi yang tersedia, gunakan 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

Argumen pertama mewakili jalur ke HRF baseline-prof.txt.

Profgen-cli juga memerlukan jalur ke build rilis APK dan peta obfuscation yang digunakan untuk meng-obfuscate APK saat menggunakan R8 atau Proguard. Dengan cara ini, profgen dapat menerjemahkan simbol sumber dalam HRF ke nama terkait yang di-obfuscate saat membuat profil yang dikompilasi.

Karena format profil ART tidak kompatibel dengan versi baru ataupun versi lama, berikan format profil sehingga profgen mengemas metadata profil (profm) yang dapat Anda gunakan untuk melakukan transcoding satu format profil ART ke format lainnya saat diperlukan.

Format profil dan versi platform

Opsi berikut tersedia saat memilih format profil:

Format profil Versi platform Level API
v0_1_5_s Android S+ 31+
v0_1_0_p Android P, Q, dan 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

Salin file output baseline.prof dan baseline.profm ke folder assets atau dexopt di APK.

Peta obfuscation

Anda hanya perlu menyediakan peta obfuscation jika HRF menggunakan simbol sumber. Jika HRF dihasilkan dari build rilis yang sudah di-obfuscate dan tidak ada pemetaan yang diperlukan, Anda dapat mengabaikan opsi tersebut dan menyalin output ke folder assets atau dexopt.

Penginstalan tradisional Profil Dasar Pengukuran

Profil Dasar Pengukuran dikirimkan secara tradisional ke perangkat dengan salah satu dari dua cara.

Menggunakan install-multiple dengan DexMetadata

Pada perangkat yang menjalankan API 28 dan yang lebih baru, klien Play mendownload payload APK dan DexMetadata (DM) untuk versi APK yang sedang diinstal. DM berisi informasi profil yang diteruskan ke Pengelola Paket di perangkat.

APK dan DM diinstal sebagai bagian dari sesi penginstalan tunggal menggunakan sesuatu seperti:

adb install-multiple base.apk base.dm

Jetpack ProfileInstaller

Pada perangkat yang menjalankan level API 29 dan yang lebih baru, library Jetpack ProfileInstaller menyediakan mekanisme alternatif untuk menginstal profil yang dikemas ke dalam assets atau dexopt setelah APK diinstal di perangkat. ProfileInstaller dipanggil oleh ProfileInstallReceiver atau oleh aplikasi secara langsung.

Library ProfileInstaller melakukan transcoding profil berdasarkan versi SDK perangkat target, dan menyalin profil ke direktori cur di perangkat (direktori staging khusus paket untuk profil ART di perangkat).

Setelah perangkat tidak ada aktivitas, profil akan diambil oleh proses yang disebut bg-dexopt di perangkat.

Melakukan sideload Profil Dasar Pengukuran

Bagian ini menjelaskan cara menginstal Profil Dasar Pengukuran yang diberi APK.

Siaran dengan androidx.profileinstaller

Pada perangkat yang menjalankan API 24 dan yang lebih baru, Anda dapat menyiarkan perintah untuk menginstal 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 tidak ada di sebagian besar APK dengan Profil Dasar Pengukuran—yang ada pada sekitar 77 ribu dari 450 ribu aplikasi di Play—meskipun ada di hampir setiap APK yang menggunakan Compose. Hal ini karena library dapat menyediakan profil tanpa mendeklarasikan dependensi di ProfileInstaller. Menambahkan dependensi di setiap library dengan profil akan berlaku mulai dari Jetpack.

Menggunakan install-multiple dengan profgen atau DexMetaData

Pada perangkat yang menjalankan API 28 dan yang lebih baru, Anda dapat melakukan sideload Profil Dasar Pengukuran tanpa harus memiliki library ProfileInstaller di aplikasi.

Untuk melakukannya, gunakan 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

Untuk mendukung pemisahan APK, jalankan langkah profil ekstrak sebelumnya, satu kali per APK. Pada waktu penginstalan, teruskan setiap APK dan file .dm terkait, dengan memastikan nama APK dan .dm cocok:

adb install-multiple appname-base.apk appname-base.dm \
appname-split1.apk appname-split1.dm

Verifikasi

Untuk memastikan profil tersebut telah diinstal dengan benar, Anda dapat menggunakan langkah-langkah yang ada di Mengukur peningkatan aplikasi secara manual.

Membuang konten profil biner

Untuk memasukkan konten versi biner Profil Dasar Pengukuran yang ringkas, gunakan opsi dumpProfile 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 memerlukan APK karena representasi biner yang ringkas hanya menyimpan offset DEX, sehingga APK diperlukan untuk merekonstruksi nama class dan metode.

Mode ketat diaktifkan secara default, dan mode ini akan memeriksa kompatibilitas profil dengan file DEX di APK. Jika Anda mencoba men-debug profil yang dihasilkan oleh alat lain, Anda mungkin akan mendapatkan kegagalan kompatibilitas yang mencegah Anda agar tidak membuang data untuk diselidiki. Dalam kasus ini, Anda dapat menonaktifkan mode ketat dengan --strict false. Namun, dalam sebagian besar kasus, Anda harus tetap mengaktifkan mode ketat.

Peta obfuscation bersifat opsional; jika disediakan. Fitur ini membantu memetakan ulang simbol-simbol yang di-obfuscate ke versi yang dapat dibaca manusia agar mudah digunakan.