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

Manuel olarak gerçekleştirilen çabayı azaltmak ve genel ölçeklenebilirliği artırmak için Jetpack Makrobenchmark kitaplığını kullanarak profil kuralı oluşturma işlemini otomatikleştirmenizi önemle tavsiye ederiz. Ancak, uygulamanızda profil kurallarını manuel olarak oluşturup ölçmek mümkündür.

Profil kurallarını manuel olarak tanımlama

src/main dizininde yer alan 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.

Dosya, satır başına bir kural belirtiyor. Her kural, uygulama veya kitaplıktaki eşleştirme yöntemleri ya da sınıflarıyla ilgili optimize edilmesi gereken bir kalıbı temsil eder.

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

Aşağıdaki örnekte Jetpack Composer kitaplığında bulunan birkaç Temel Profil 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;

Kural söz dizimi

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

[FLAGS][CLASS_DESCRIPTOR]->[METHOD_SIGNATURE]

Bir sınıf kuralı aşağıdaki modeli 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üne göre Hot, Startup veya Post Startup olarak işaretlenmesinin gerekip gerekmediğini belirtmek için H, S ve P karakterlerinden bir veya daha fazlasını temsil eder.

H işaretli bir yöntem, bunun "sıcak" bir yöntem olduğunu, yani uygulamanın kullanım süresi boyunca birçok kez çağrıldığını gösterir.

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

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

Bu dosyada bulunan bir sınıf, başlangıç sırasında kullanıldığını ve sınıf yükleme maliyetini önlemek için yığında önceden ayrılması gerektiğini gösteriyor. ART derleyicisi, bu yöntemlerin AOT derlemesi ve oluşturulan AOT dosyasında düzen optimizasyonları gibi çeşitli optimizasyon stratejileri kullanır.
CLASS_DESCRIPTOR Hedeflenen yöntemin sınıfı için açıklayıcı. Örneğin, androidx.compose.runtime.SlotTable, Landroidx/compose/runtime/SlotTable; şeklinde bir açıklayıcıya sahiptir. L ifadesi, Dalvik Yürütülebilir (DEX) biçimi uyarınca buraya eklenir.
METHOD_SIGNATURE Yöntemin adı, parametre türleri ve döndürme türleri de dahil olmak üzere yöntemin imzası. Örneğin:

// LayoutNode.kt

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

LayoutNode üzerinde isPlaced()Z imzasına sahip.

Bu kalıplar, tek bir kuralın birden fazla yöntemi veya sınıfı kapsamasını sağlamak için joker karakterler içerebilir. Android Studio'da kural söz dizimiyle yazma konusunda rehberli yardım almak için Android Baseline Profiles eklentisine bakın.

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 Yürütülebilir (DEX) biçimine bakın.

Karakter Tür Açıklama
B bayt İmzalanmış bayt
C karakter UTF-16'da kodlanmış Unicode karakter kod noktası
D çift Çift duyarlıklı kayan nokta değeri
F kayan Tek duyarlıklı kayan nokta değeri
I int Tam sayı
J uzun Uzun tam sayı
S kısa video Kısa olarak imzalandı
V geçersiz Geçersiz
Z boole Doğru veya yanlış
L (sınıf adı) reference Sınıf adı örneği

Ayrıca kitaplıklar, AAR yapılarında paketlenmiş kurallar tanımlayabilir. Bu yapıları içerecek bir APK oluşturduğunuzda, kurallar birleştirilir (manifest birleştirme işleminin yapılmasına benzer şekilde) ve APK'ya özel kompakt bir ikili ART profili olarak derlenir.

ART, Android 9 (API düzeyi 28) veya ProfileInstaller kullanılırken Android 7 (API düzeyi 24) üzerinde yükleme sırasında uygulamanın belirli bir alt kümesini AOT tarafından derlenen cihazlarda APK kullanıldığında bu profilden yararlanır.

Temel Profilleri manuel olarak topla

Makrobenchmark kitaplığını ayarlamadan manuel olarak bir Temel Profil oluşturabilir ve kritik kullanıcı yolculuklarınız için kullanıcı arayüzü otomasyonları oluşturabilirsiniz. Makrobenchmark'ları kullanmanızı önersek de bu her zaman mümkün olmayabilir. Örneğin, Gradle dışında bir derleme sistemi kullanıyorsanız Baseline Profile Gradle eklentisini kullanamazsınız. Bu tür durumlarda, Temel Profil kurallarını manuel olarak toplayabilirsiniz. API 34 ve sonraki sürümleri çalıştıran bir cihaz veya emülatör kullanıyorsanız bu işlem çok daha kolay olur. Daha düşük API düzeylerinde de bu mümkün olsa da kök erişimi gerekir ve AOSP görüntüsü çalıştıran bir emülatör kullanmanız gerekir. Aşağıdakileri yaparak kuralları doğrudan toplayabilirsiniz:

  1. Uygulamanızın sürümünü bir test cihazına yükleyin. Doğru bir profil için uygulama derleme türü, R8 için optimize edilmiş ve hata ayıklanamaz olmalıdır.
  2. Profillerin önceden derlenmediğinden emin olun.

    API 34 ve sonraki sürümleri

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

    API 33 ve önceki sürümler

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

    APK'nızın Jetpack Profile Yükleyici kitaplığına bir bağımlılığı varsa kitaplık, APK'nızın ilk kez başlatılmasında bir profili önyükler. Bu durum, profil oluşturma sürecini engelleyebilir. Bu nedenle, aşağıdaki komutu kullanarak bu özelliği devre dışı bırakın:

    adb shell am broadcast -a androidx.profileinstaller.action.SKIP_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
    

  3. Uygulamayı çalıştırın ve profil toplamak istediğiniz kritik kullanıcı yolculuklarında manuel olarak gezinin.
  4. ART'dan profillerin dökümünü oluşturmasını isteyin. APK'nızın Jetpack Profile Yükleyici kitaplığına bir bağımlılığı varsa, profillerin dökümünü almak için bunu kullanın:

    adb shell am broadcast -a androidx.profileinstaller.action.SAVE_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
    adb shell am force-stop $PACKAGE_NAME
    
    Profil Yükleyici'yi kullanmıyorsanız aşağıdaki komutu kullanarak profilleri bir emülatöre manuel olarak dökün:

    adb root
    adb shell killall -s SIGUSR1 $PACKAGE_NAME
    adb shell am force-stop $PACKAGE_NAME
    

  5. Profil oluşturma işleminin tamamlanması için en az beş saniye bekleyin.
  6. Oluşturulan ikili programları metne dönüştürün:

    API 34 ve sonraki sürümleri

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

    API 33 ve önceki sürümler

    Bir referans profilinin veya mevcut bir profilin oluşturulup oluşturulmadığını belirleyin. Referans profili şu konumda bulunur:

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

    Bir profil şu konumda bulunuyor:

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

    APK'nın konumunu belirleyin:

    adb root
    adb shell pm path $PACKAGE_NAME
    

    Dönüştürme işlemini 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
    

  7. Cihazdan döküm profili almak için adb öğesini 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 derlediğinizde Temel Profil eklenir. Bunu doğrulamak için Yükleme sorunları bölümündeki adımları uygulayın.

Uygulama iyileştirmelerini manuel olarak ölçme

Uygulama iyileştirmelerini karşılaştırma yoluyla ölçmenizi önemle tavsiye ederiz. Bununla birlikte, iyileştirmeleri manuel olarak ölçmek isterseniz optimize edilmemiş uygulama başlangıcını referans olarak ölçerek işe 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, Temel Profili başka cihazdan 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 derlenen durumu sıfırlamadan uygulama başlatma performansını önceden olduğu 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, Temel Profil'in kompakt ikili sürümünü oluştururken profgen aracının ne yaptığı açıklanmaktadır.

Profgen-cli; profil derleme, iç gözlem ve ART profillerinin çevrilmesine yardımcı olur. Böylece hedef SDK sürümünden bağımsız olarak Android destekli cihazlara yüklenebilirler.

Profgen-cli, Referans Profilin HRF'sini derlenen biçimiyle derleyen bir KSA'dır. CLI, Android SDK'nın bir parçası olarak cmdline-tools deposunda da gönderilir.

Bu özellikler studio-main dalında sunulmaktadır:

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

Profgen-cli ile kompakt ikili program profilleri oluşturun.

Profgen-cli ile kullanılabilen komutlar şunlardır: bin, validate ve dumpProfile. Kullanılabilir komutları görmek için profgen --help komutunu 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

Kompakt ikili program profilini 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 \

Mevcut seçenekleri görmek için profgen bin options_list öğesini 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 temsil eder.

Profgen-cli ayrıca APK'nın yayın derlemesine giden yola ve R8 veya ProGuard'ı kullanırken APK'yı karartmak için kullanılan bir karartma haritasına da ihtiyacı vardır. Bu şekilde profgen, derlenen profili oluştururken HRF'deki kaynak simgelerini, bunları karartılmış adlarına çevirebilir.

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

Profil biçimleri ve platform sürümleri

Profil biçimi seçerken aşağıdaki seçenekleri kullanabilirsiniz:

Profil biçimi Platform sürümü API seviyesi
s0_1_5_s Android S+ 31+
s0_1_0_p Android P, Q ve R 28-30
v0_0_9_omr1 Android O MR1 27
s0_0_5_o Android O 26
s0_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ı

Kod karartma haritasını yalnızca HRF'de kaynak sembolleri kullanılıyorsa sağlamanız gerekir. HRF, kodu karartılmış bir sürüm derlemesinden oluşturulmuşsa ve eşleme gerekmiyorsa bu seçeneği yoksayıp çıkışları assets veya dexopt klasörüne kopyalayabilirsiniz.

Temel Profillerin geleneksel kurulumu

Temel Profiller, geleneksel olarak bir cihaza iki şekilde yayınlanır.

install-multiple öğesini DexMetadata ile kullanma

API 28 ve sonraki sürümleri çalıştıran cihazlarda Play istemcisi, yüklenmekte olan bir APK sürümüne ait APK veDexMetadata (DM) yükünü indirir. DM, cihazda Paket Yöneticisi'ne iletilen profil bilgilerini içerir.

APK ve DM, aşağıdakine benzer bir şekilde tek bir yükleme oturumunun parçası olarak yüklenir:

adb install-multiple base.apk base.dm

Jetpack Profil Yükleyicisi

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

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

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

Temel Profili başka cihazdan yükleme

Bu bölümde, belirli bir APK için Temel Profil'in nasıl yükleneceği açıklanmaktadır.

androidx.profileinstaller ile anons yapın

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, Temel Profillere sahip çoğu APK'da mevcut değildir. Temel Profiller, Play'deki 450 bin uygulamanın yaklaşık 77.000'inde yer almaktadır. Ancak Compose'u kullanan her APK'da da etkin bir şekilde bulunur. Bunun nedeni, kitaplıkların ProfileInstaller'a bir bağımlılık bildirmeden profil sunabilmesidir. Profilli her kitaplığa bağımlılık eklemek Jetpack'ten itibaren geçerlidir.

install-multiple ürününü profgen veya DexMetaData ile kullanın

API 28 ve sonraki sürümleri çalıştıran cihazlarda, uygulamada ProfileInstaller kitaplığına ihtiyaç duymadan Temel Profili başka cihazdan yükleyebilirsiniz.

Bunun 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 önceki ayıklama profili adımlarını her APK için bir kez çalıştırın. Yükleme sırasında her APK ve ilişkili .dm dosyasını ileterek 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 program profilinin içeriğini boşaltma

Bir Temel Profilin kompakt ikili sürümünün içeriğini derinlemesine 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 sınıf ve yöntem adlarını yeniden oluşturmak için bunlara ihtiyaç duyduğu için APK'ya ihtiyaç duyar.

Yüksek düzey modu varsayılan olarak etkinleştirilir ve bu seçenek, profilin APK'daki DEX dosyaları ile uyumluluk kontrolü gerçekleştirir. Başka bir araç tarafından oluşturulan profillerde hata ayıklamaya çalışıyorsanız, inceleme için döküm çıkarabilmenizi engelleyen uyumluluk hataları alabilirsiniz. Bu tür durumlarda, --strict false ile yüksek düzey modunu devre dışı bırakabilirsiniz. Ancak çoğu durumda yüksek düzey modunu etkin tutmanız gerekir.

Karartma haritası isteğe bağlıdır. Sağlandığında, kullanım kolaylığı için kod karartma haritalarının, kullanıcılar tarafından okunabilen versiyonlarıyla yeniden eşleştirilmesine yardımcı olur.