Referans Profilleri manuel olarak oluşturma ve ölçme

Manuel çabayı azaltmak ve genel ölçeklenebilirliği artırmak için Jetpack Macrobenchmark kitaplığını kullanarak profil kurallarının oluşturulmasını otomatikleştirmenizi önemle tavsiye ederiz. Ancak uygulamanızda profil kurallarını manuel olarak oluşturup ölçebilirsiniz.

Profil kurallarını manuel olarak tanımlama

src/main dizininde bulunan baseline-prof.txt adlı bir dosya oluşturarak profil kurallarını bir uygulamada veya kitaplık modülünde manuel olarak tanımlayabilirsiniz. Bu, AndroidManifest.xml dosyasını içeren klasörle aynıdır.

Dosyada her satırda bir kural belirtilir. Her kural, uygulamada veya kitaplıkta optimize edilmesi gereken yöntemlerin ya da sınıfların eşleştirilmesine yönelik bir kalıbı temsil eder.

Bu kuralların söz dizimi, adb shell profman --dump-classes-and-methods kullanılırken okunabilir ART profili biçiminin (HRF) üst kümesidir. Söz dizimi, tanımlayıcılar ve imzalar için kullanılan söz dizimine benzer ancak kural yazma sürecini basitleştirmek için joker karakterlerin kullanılmasına olanak tanır.

Aşağıdaki örnekte, Jetpack Compose kitaplığında bulunan birkaç Baseline Profile kuralı gösterilmektedir:

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;

Bu örnek Compiler Explorer projesinde profil kurallarını değiştirmeyi deneyebilirsiniz. Compiler Explorer'ın yalnızca okunabilir ART profil biçimini (HRF) desteklediğini, bu nedenle joker karakterlerin desteklenmediğini unutmayın.

Kural söz dizimi

Bu kurallar, yöntemleri veya sınıfları hedeflemek için iki biçimden birini alır:

[FLAGS][CLASS_DESCRIPTOR]->[METHOD_SIGNATURE]

Sınıf kuralı şu düzeni kullanır:

[CLASS_DESCRIPTOR]

Ayrıntılı açıklama için aşağıdaki tabloya bakın:

Sözdizimi Açıklama
FLAGS Bu yöntemin başlangıç türüyle ilgili olarak Hot, Startup veya Post Startup olarak işaretlenmesi gerekip gerekmediğini belirtmek için H, S ve P karakterlerinden birini veya daha fazlasını temsil eder.

H işaretli bir yöntem, "sık kullanılan" bir yöntem olduğunu gösterir. Bu yöntem, uygulamanın kullanım ömrü boyunca birçok kez çağrılır.

S işaretli bir yöntem, başlatma sırasında çağrılan bir yöntem olduğunu gösterir.

P işaretli bir yöntem, başlatma işleminden sonra çağrılan bir yöntem olduğunu gösterir.

Bu dosyada bulunan bir sınıf, başlatma sırasında kullanıldığını ve sınıf yükleme maliyetini önlemek için yığında önceden ayrılması gerektiğini gösterir. ART derleyicisi, bu yöntemlerin AOT derlemesi ve oluşturulan AOT dosyasında düzen optimizasyonları gerçekleştirme gibi çeşitli optimizasyon stratejileri kullanır.
CLASS_DESCRIPTOR Hedeflenen yöntemin sınıfı için tanımlayıcı. Örneğin, androidx.compose.runtime.SlotTable öğesinin tanımlayıcısı Landroidx/compose/runtime/SlotTable;'dir. Burada, Dalvik Executable (DEX) biçimine göre L öne eklenir.
METHOD_SIGNATURE Yöntemin adı, parametre türleri ve dönüş türleri dahil olmak üzere yöntemin imzası. Örneğin:

// LayoutNode.kt

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

LayoutNode adresindeki isPlaced()Z imzası.

Bu kalıplarda, tek bir kuralın birden fazla yöntemi veya sınıfı kapsaması için joker karakterler olabilir. Android Studio'da kural söz dizimiyle yazarken rehberli yardım almak için Android Baseline Profiles eklentisine bakın.

Bir joker karakter kuralı örneği şu şekilde görünebilir:

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

Temel profil kurallarında desteklenen türler

Temel Profil kuralları aşağıdaki türleri destekler. Bu türlerle ilgili ayrıntılar için Dalvik Executable (DEX) biçimi başlıklı makaleyi inceleyin.

Karakter Tür Açıklama
B bayt İşaretli bayt
C char UTF-16 ile kodlanmış Unicode karakter kod noktası
D çift Çift duyarlıklı kayan noktalı değer
F float Tek duyarlıklı kayan noktalı değer
I int Tam sayı
J uzun Uzun tam sayı
S kısa İmzalı kısa video
V geçersiz Geçersiz kılma
Z boole Doğru veya yanlış
L (sınıf adı) referans Sınıf adının bir örneği

Ayrıca kitaplıklar, AAR yapıtlarında paketlenmiş kurallar tanımlayabilir. Bu yapıtları içerecek bir APK oluşturduğunuzda kurallar, manifest birleştirme işlemine benzer şekilde birleştirilir ve APK'ya özgü kompakt bir ikili ART profili olarak derlenir.

ART, APK cihazlarda kullanıldığında bu profilden yararlanarak Android 9'da (API düzeyi 28) yükleme sırasında veya ProfileInstaller kullanılırken Android 7'de (API düzeyi 24) uygulamanın belirli bir alt kümesini AOT derlemesi yapar.

Temel profilleri manuel olarak toplama

Macrobenchmark kitaplığını ayarlamadan temel profil oluşturabilir ve önemli kullanıcı yolculuklarınızın kullanıcı arayüzü otomasyonlarını oluşturabilirsiniz. Macrobenchmark'ları kullanmanızı önersek de bu her zaman mümkün olmayabilir. Örneğin, Gradle dışı bir derleme sistemi kullanıyorsanız Baseline Profile Gradle eklentisini kullanamazsınız. Bu gibi durumlarda, Baseline Profile kurallarını manuel olarak toplayabilirsiniz. API 34 ve sonraki sürümlerin yüklü olduğu bir cihaz veya emülatör kullanıyorsanız bu işlem çok daha kolaydır. Daha düşük API düzeylerinde bu işlem hâlâ mümkün olsa da kök erişimi gerektirir ve AOSP görüntüsü çalıştıran bir emülatör kullanmanız gerekir. Aşağıdaki işlemleri yaparak kuralları doğrudan toplayabilirsiniz:

  1. Uygulamanızın yayın sürümünü bir test cihazına yükleyin. Uygulama derleme türü, derleme sistemi tarafından kullanılabilecek bir profil yakalamak için R8 ile optimize edilmemeli ve hata ayıklanabilir olmamalıdır.
  2. Profil yüklemeyi devre dışı bırakın ve uygulamayı kapatın.

    APK'nızın Jetpack Profile Installer kitaplığına bağımlılığı varsa kitaplık, APK'nızın ilk başlatılmasında bir profil oluşturur. Bu durum, profil oluşturma sürecini etkileyebilir. Bu nedenle, aşağıdaki komutla devre dışı bırakın:

    adb shell am broadcast -a androidx.profileinstaller.action.SKIP_FILE WRITE_SKIP_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
  3. Uygulama derlemesini sıfırlayın ve tüm profilleri temizleyin.

    API 34 ve sonraki sürümler

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

    API 33 ve altı

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

  4. Uygulamayı çalıştırın ve profilini toplamak istediğiniz kritik kullanıcı yolculuklarınızda manuel olarak gezinin.

  5. Profillerin dengelenmesi için en az beş saniye bekleyin.

  6. Kaydetme işlemini gerçekleştirin ve kaydetmenin tamamlanmasını bekleyin. APK'nızın Jetpack Profile Installer kitaplığına bağımlılığı varsa profilleri boşaltmak için bu kitaplığı kullanın:

    adb shell am broadcast -a androidx.profileinstaller.action.SAVE_PROFILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
    sleep 1 # wait 1 second
    adb shell am force-stop $PACKAGE_NAME
    Profil Yükleyici'yi kullanmıyorsanız aşağıdaki komutu kullanarak profilleri bir emülatörde manuel olarak boşaltın:

    adb root
    adb shell killall -s SIGUSR1 $PACKAGE_NAME
    sleep 1 # wait 1 second
    adb shell am force-stop $PACKAGE_NAME

  7. Oluşturulan ikili profilleri metne dönüştürme:

    API 34 ve sonraki sürümler

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

    API 33 ve altı

    Referans profil mi yoksa mevcut profil mi oluşturulduğunu belirleyin. Referans profili aşağıdaki konumda bulunur:

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

    Geçerli bir profil şu konumda bulunur:

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

    APK'nın konumunu belirleyin:

    adb root
    adb shell pm path $PACKAGE_NAME

    Dönüşümü gerçekleştirin:

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

  8. Dökümü alınan profili cihazdan almak için adb komutunu kullanın:

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

Bu işlem, oluşturulan profil kurallarını çeker ve uygulama modülünüze yükler. Uygulamayı bir sonraki derlemenizde Baseline Profile dahil edilir. Yükleme sorunları başlıklı makaledeki adımları uygulayarak bu durumu doğrulayın.

Uygulama iyileştirmelerini manuel olarak ölçme

Uygulama iyileştirmelerini karşılaştırma yoluyla ölçmenizi önemle tavsiye ederiz. Ancak iyileştirmeleri manuel olarak ölçmek isterseniz referans için optimize edilmemiş uygulama başlatma süresini ölçerek başlayabilirsiniz.

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"

Ardından, Baseline Profile'ı yan yükleyin.

# 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

Paketin yükleme sırasında optimize edildiğini doğrulamak için aşağıdaki komutu çalıştırın:

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

Çıkış, paketin derlendiğini belirtmelidir:

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

Artık uygulama başlatma performansını derlenmiş durumu sıfırlamadan önceki gibi ölçebilirsiniz. Paketin derlenmiş durumunu sıfırlamadığınızdan emin olun.

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

Temel profiller ve profgen

Bu bölümde, profgen aracının temel profilin kompakt ikili sürümünü oluştururken ne yaptığı açıklanmaktadır.

Profgen-cli, profil derleme, inceleme ve ART profillerini dönüştürme işlemlerine yardımcı olur. Böylece, hedef SDK sürümünden bağımsız olarak Android destekli cihazlara yüklenebilirler.

Profgen-cli, bir Baseline Profile'ın HRF'sini derlenmiş biçimine derleyen bir KSA'dır. KSA, Android SDK'nın bir parçası olarak cmdline-tools deposunda da bulunur.

Bu özellikler studio-main dalında kullanılabilir:

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

Profgen-cli ile kompakt ikili profiller oluşturma

Profgen-cli ile kullanılabilen komutlar bin, validate ve dumpProfile'dir. Kullanılabilir komutları görmek için profgen --help tuşunu kullanın:

  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

Küçük ikili profil oluşturmak için bin komutunu kullanın. Aşağıda örnek bir çağrı verilmiştir:

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

Kullanılabilir seçenekleri görmek için profgen bin options_list kullanın:

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

İlk bağımsız değişken, baseline-prof.txt HRF'nin yolunu gösterir.

Profgen-cli ayrıca APK'nın yayın derlemesinin yolunu ve R8 veya Proguard kullanılırken APK'yı karartmak için kullanılan bir karartma haritasını da gerektirir. Bu sayede profgen, derlenmiş profili oluştururken HRF'deki kaynak sembolleri, karşılık gelen karartılmış adlara çevirebilir.

ART profili biçimleri ileri veya geri uyumlu olmadığından, gerektiğinde bir ART profili biçimini diğerine dönüştürmek için kullanabileceğiniz profgen paketlerinin profil meta verilerini (profm) içeren bir profil biçimi sağlayın.

Profil biçimleri ve platform sürümleri

Profil biçimi seçerken aşağıdaki seçenekler kullanılabilir:

Profil biçimi Platform sürümü API seviyesi
v0_1_5_s Android S+ 31+
v0_1_0_p Android P, Q ve 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

baseline.prof ve baseline.profm çıkış dosyalarını APK'daki assets veya dexopt klasörüne kopyalayın.

Kod karartma haritaları

Yalnızca HRF kaynak sembolleri kullanıyorsa karartma haritasını sağlamanız gerekir. HRF, halihazırda karartılmış bir yayın derlemesinden oluşturuluyorsa ve eşleme gerekmiyorsa bu seçeneği yoksayabilir ve çıktıları assets veya dexopt klasörüne kopyalayabilirsiniz.

Temel profillerin geleneksel olarak yüklenmesi

Temel profiller geleneksel olarak cihazlara iki şekilde sunulur.

install-multiple uygulamasını DexMetadata ile kullanma

API 28 ve sonraki sürümlerin yüklü olduğu cihazlarda Play istemcisi, yüklenen APK sürümü için APK ve DexMetadata (DM) yükünü indirir. DM, cihazdaki Paket Yöneticisi'ne aktarılan profil bilgilerini içerir.

APK ve DM, aşağıdakine benzer bir yöntemle tek bir yükleme oturumu kapsamında yüklenir:

adb install-multiple base.apk base.dm

Jetpack ProfileInstaller

API düzeyi 29 ve sonraki sürümleri çalıştıran cihazlarda Jetpack ProfileInstaller kitaplığı, APK cihazda yüklendikten sonra assets veya dexopt içine paketlenmiş bir profili yüklemek için alternatif bir mekanizma sağlar. ProfileInstaller, ProfileInstallReceiver veya doğrudan uygulama tarafından çağrılır.

ProfileInstaller kitaplığı, profili hedef cihazın SDK sürümüne göre dönüştürür ve profili cihazdaki cur dizinine kopyalar (cihazdaki ART profilleri için pakete özel bir hazırlama dizini).

Cihaz boşta kaldıktan sonra profil, cihazda bg-dexopt adlı bir işlem tarafından alınır.

Temel profil yükleme

Bu bölümde, bir APK verildiğinde temel profilin nasıl yükleneceği açıklanmaktadır.

androidx.profileinstaller ile anons yapma

API 24 ve sonraki sürümleri çalıştıran cihazlarda, profili yüklemek için bir komut yayınlayabilirsiniz:

# 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, Baseline Profilleri'ne sahip çoğu APK'da bulunmaz. Bu APK'lar, Play'deki 450.000 uygulamanın yaklaşık 77.000'ini oluşturur. ProfileInstaller, Compose kullanan hemen hemen her APK'da bulunur. Bunun nedeni, kitaplıkların ProfileInstaller'a bağımlılık beyan etmeden profiller sağlayabilmesidir. Her kitaplığa profilli bağımlılık ekleme işlemi Jetpack'ten itibaren geçerlidir.

install-multiple'yı profgen veya DexMetaData ile kullanma

API 28 ve sonraki sürümlerin yüklü olduğu cihazlarda, uygulamada ProfileInstaller kitaplığına sahip olmanıza gerek kalmadan bir Baseline Profile'ı yan yükleyebilirsiniz.

Bunu yapmak için Profgen-cli'yi kullanın:

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

APK bölmelerini desteklemek için yukarıdaki profil ayıklama adımlarını APK başına bir kez çalıştırın. Yükleme sırasında her APK'yı ve ilişkili .dm dosyasını iletin. APK ve .dm adlarının eşleştiğinden emin olun:

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

Doğrulama

Profilin doğru şekilde yüklendiğini doğrulamak için Uygulama iyileştirmelerini manuel olarak ölçme bölümündeki adımları kullanabilirsiniz.

İkili profilin içeriğini boşaltma

Bir temel profilin kompakt ikili sürümünün içeriğini incelemek için Profgen-cli dumpProfile seçeneğini kullanın:

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, kompakt ikili gösterim yalnızca DEX ofsetlerini depoladığından ve bu nedenle sınıf ve yöntem adlarını yeniden oluşturmak için bunlara ihtiyaç duyduğundan APK'ya ihtiyaç duyar.

Katı mod varsayılan olarak etkindir ve bu mod, APK'daki DEX dosyalarıyla profilin uyumluluk kontrolünü gerçekleştirir. Başka bir araç tarafından oluşturulan profillerde hata ayıklamaya çalışıyorsanız inceleme için döküm almanızı engelleyen uyumluluk hataları alabilirsiniz. Bu gibi durumlarda, --strict false ile yüksek güvenlik modunu devre dışı bırakabilirsiniz. Ancak çoğu durumda yüksek güvenlik modunu etkin tutmanız gerekir.

Karartma haritası isteğe bağlıdır. Sağlandığında, karartılmış sembollerin okunabilir sürümlerine yeniden eşlenmesine yardımcı olarak kullanım kolaylığı sağlar.