我們強烈建議使用 Jetpack Macrobenchmark 程式庫自動產生設定檔規則,因為這樣可以減少人力作業並提高一般擴充性。不過,您可以在應用程式中手動建立及評估設定檔規則。
手動定義設定檔規則
您可以透過在 src/main
目錄中建立名為 baseline-prof.txt
的檔案,手動定義應用程式或程式庫模組中的設定檔規則。這就是存放 AndroidManifest.xml
檔案的同一個資料夾。
在這個檔案中,每一行會指定一個規則。每個規則都代表一種模式,用來比對應用程式/程式庫中需要最佳化的方法或類別。
使用 adb shell profman --dump-classes-and-methods
時,這些規則的語法是一個人類可讀的 ART 設定檔格式 (HRF) 超集。語法和描述元及特徵標記的語法類似,但允許使用萬用字元來簡化規則編寫程序。
下列範例列出 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;
您可以嘗試修改這個範例 Compiler Explorer 專案中的設定檔規則。請注意,Compiler Explorer 只支援人類可讀的 ART 設定檔格式 (HRF),因此不支援萬用字元。
規則語法
這些規則能以兩種模式之一來指定方法或類別:
[FLAGS][CLASS_DESCRIPTOR]->[METHOD_SIGNATURE]
類別規則使用以下模式:
[CLASS_DESCRIPTOR]
請參閱下表的詳細說明:
語法 | 說明 |
---|---|
FLAGS |
代表 H 、S 和 P 的一或多個字元,點出此方法必須標記為 Hot 、Startup 或 Post Startup ,與啟動類型相關。具有 H 標記表示這是個「熱門」方法;意即在應用程式生命週期間,系統會多次呼叫這個方法。具有 S 標記表示系統會在應用程式啟動時,呼叫這個方法。具有 P 標記表示系統會在應用程式啟動後,呼叫這個方法。在這個檔案中可以看到的類別,代表會在程式啟動時使用。必須在堆積中預先分配好,才能避免無謂的類別載入作業。ART 編譯器採用多種最佳化策略:例如上述的 AOT 編譯方法,及在已產生的 AOT 檔案內,就版面配置進行最佳化處理。 |
CLASS_DESCRIPTOR |
指定方法類別的描述元。舉例來說,androidx.compose.runtime.SlotTable 的描述元是 Landroidx/compose/runtime/SlotTable; 。系統會依據 Dalvik Executable (DEX) 格式在開頭加上 L 字。 |
METHOD_SIGNATURE |
方法的特徵標記,包括名稱、參數類型和傳回類型。舉例來說,LayoutNode 上的 // LayoutNode.kt fun isPlaced():Boolean { // ... } 帶有 isPlaced()Z 特徵標記。 |
這些模式可納入萬用字元,這樣一條規則就能涵蓋多種方法或類別。如果使用 Android Studio 的規則語法編寫時,需要引導或協助,請參考 Android 基準設定檔外掛程式。
萬用字元規則的範例如下:
HSPLandroidx/compose/ui/layout/**->**(**)**
基準設定檔規則的支援類型
基準設定檔規則支援下列類型。如要進一步瞭解這些類型,請參考 Dalvik Executable (DEX) 格式。
字元 | 類型 | 說明 |
---|---|---|
B |
byte | 有符號的位元組 |
C |
char | 以 UTF-16 編碼的萬國碼字元碼點 |
D |
double | 雙精度浮點值 |
F |
float | 單精度浮點值 |
I |
int | 整數 |
J |
long | 長整數 |
S |
short | 有符號的短整數 |
V |
void | 無效 |
Z |
布林值 | true 或 false |
L (類別名稱) |
參照 | 類別名稱的例子 |
此外,程式庫也可以規範放在 AAR 構件中的規則。當您建構 APK 以納入這些構件時,系統會將規則合併在一起 (類似於資訊清單的合併方式),並編譯為 APK 專用的精簡二進位 ART 設定檔。
當裝置搭載 Android 9 (API 級別 28),並在安裝期間使用 APK 預先編譯特定的應用程式子集,ART 就會使用這個設定檔。若裝置搭載 Android 7 (API 級別 24) 並使用 ProfileInstaller
,ART 也會使用這個設定檔。
手動收集基準設定檔
您可以手動產生基準設定檔,而無須設定 Macrobenchmark 程式庫,並為關鍵使用者旅程建立 UI 自動化動作。雖然我們建議使用 Macrobenchmarks,但不一定適用於所有情況。舉例來說,如果您使用非 Gradle 建構系統,就無法使用基準設定檔 Gradle 外掛程式。在這種情況下,您可以手動收集基準設定檔規則。如果您使用搭載 API 34 以上版本的裝置或模擬器,這項操作會變得更加簡單。雖然在較低的 API 級別中仍可執行此操作,但需要 Root 存取權,且您必須使用執行 AOSP 映像檔的模擬器。您可以按照下列步驟直接收集規則:
- 在測試裝置上安裝應用程式的發布版本。應用程式建構類型必須經過 R8 最佳化,且無法進行偵錯,才能取得準確的設定檔。
- 請確認設定檔尚未編譯。
API 34 以上版本
adb shell cmd package compile -f -m verify $PACKAGE_NAME adb shell pm art clear-app-profiles $PACKAGE_NAME
API 33 以下
adb root adb shell cmd package compile --reset $PACKAGE_NAME
如果 APK 依附於 Jetpack Profile Installer 程式庫,該程式庫會在首次啟動 APK 時啟動設定檔。這可能會干擾設定檔產生程序,因此請使用下列指令停用這項功能:
adb shell am broadcast -a androidx.profileinstaller.action.SKIP_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
- 執行應用程式,並手動瀏覽要收集設定檔的關鍵使用者旅程。
- 請 ART 轉儲設定檔。如果您的 APK 依附於 Jetpack Profile Installer 程式庫,請使用該程式庫傾印設定檔:
adb shell am broadcast -a androidx.profileinstaller.action.SAVE_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver adb shell am force-stop $PACKAGE_NAME
如果您未使用設定檔安裝工具,請使用下列指令在模擬器上手動轉儲設定檔:adb root adb shell killall -s SIGUSR1 $PACKAGE_NAME adb shell am force-stop $PACKAGE_NAME
- 等待至少五秒,讓設定檔產生作業完成。
- 將產生的二進位設定檔轉換為文字:
API 34 以上版本
adb shell pm dump-profiles --dump-classes-and-methods $PACKAGE_NAME
API 33 以下
判斷是否已建立參考設定檔或目前設定檔。參考設定檔位於以下位置:
/data/misc/profiles/ref/$$PACKAGE_NAME/primary.prof
目前的設定檔位於以下位置:
/data/misc/profiles/cur/0/$PACKAGE_NAME/primary.prof
判斷 APK 的位置:
adb root adb shell pm path $PACKAGE_NAME
執行轉換:
adb root adb shell profman --dump-classes-and-methods --profile-file=$PROFILE_PATH --apk=$APK_PATH > /data/misc/profman/$PACKAGE_NAME-primary.prof.txt
- 使用
adb
從裝置擷取已傾印的設定檔:adb pull /data/misc/profman/$PACKAGE_NAME-primary.prof.txt PATH_TO_APP_MODULE/src/main/
這會擷取產生的設定檔規則,並將其安裝到應用程式模組。下次建構應用程式時,系統就會納入基準設定檔。如要確認這項資訊,請按照「安裝問題」一文中的步驟操作。
手動評估應用程式改善情形
強烈建議您透過基準測試評估應用程式改善情形。不過,如要手動評估改善程度,您可以先評估未經最佳化的應用程式啟動效能,當做參考。
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"
接著,側載基準設定檔。
# 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
為確認套件在安裝時是否已完成最佳化,請執行下列指令:
# Check dexopt state.
adb shell dumpsys package dexopt | grep -A 1 $PACKAGE_NAME
輸出結果必須顯示套件已完成編譯:
[com.example.app]
path: /data/app/~~YvNxUxuP2e5xA6EGtM5i9A==/com.example.app-zQ0tkJN8tDrEZXTlrDUSBg==/base.apk
arm64: [status=speed-profile] [reason=install-dm]
現在可以像之前一樣評估應用程式啟動效能,但不會重設已編譯的狀態。請確保不會重設套件的已編譯狀態。
# 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"
基準設定檔和 Profgen
本節說明「Profgen」工具在為基準設定檔建構精簡二進位檔版本時執行的動作。
Profgen-cli 可協助您編譯設定檔、自我檢查,以及轉譯 ART 設定檔,無論目標 SDK 版本為何,都能在 Android 裝置上安裝設定檔。
Profgen-cli 是 CLI,可將基準設定檔的 HRF 編譯為其本身的編譯格式。CLI 也會做為 Android SDK 的一部分傳送至 cmdline-tools
存放區。
studio-main
分支版本提供以下功能:
➜ ../cmdline-tools/latest/bin
apkanalyzer
avdmanager
lint
profgen
retrace
screenshot2
sdkmanager
使用 Profgen-cli 建構密集二進位設定檔
Profgen-cli 可用的指令為 bin
、validate
和 dumpProfile
。如要查看可用的指令,請使用 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
使用 bin
指令產生精簡二進位設定檔。以下是叫用範例:
profgen bin ./baseline-prof.txt \
--apk ./release.apk \
--map ./obfuscation-map.txt \
--profile-format v0_1_0_p \
--output ./baseline.prof \
如要查看可用的選項,請使用 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
第一個引數代表 baseline-prof.txt
HRF 的路徑。
Profgen-cli 也需要 APK 的發布子版本路徑,以及在使用 R8 或 Proguard 時,用於將 APK 模糊處理的模糊處理對應。這樣一來,profgen
就能在建構已編譯的設定檔時,將 HRF 中的來源符號轉譯成對應的模糊化名稱。
ART 設定檔格式沒有前瞻相容或回溯相容的性質,因此請提供設定檔格式,讓 profgen
封裝設定檔中繼資料 (profm
),方便您視需要將 ART 設定檔轉碼為另一種格式。
設定檔格式和平台版本
選擇設定檔格式時,可用的選項如下:
設定檔格式 | 平台版本 | API 級別 |
---|---|---|
v0_1_5_s | Android S+ | 31 以上 |
v0_1_0_p | Android P、Q 和 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
和 baseline.profm
輸出檔案複製到 APK 中的 assets
或 dexopt
資料夾。
模糊處理對應
只有在 HRF 使用來源符號時,才需要提供模糊處理對應。如果 HRF 是由經過模糊處理的發布子版本產生,且不一定需要對應,可以忽略該選項,並將輸出內容複製到 assets
或 dexopt
資料夾。
以傳統方式安裝基準設定檔
一般而言,有兩種方法可將基準設定檔傳送到裝置。
將 install-multiple
與 DexMetadata 搭配使用
在搭載 API 28 以上版本的裝置上,Play 用戶端會下載所安裝 APK 版本的 APK 和 DexMetadata (DM) 酬載。該 DM 包含傳遞至裝置上套件管理工具的設定檔資訊。
APK 和 DM 會在單次安裝工作階段中,採用以下形式安裝:
adb install-multiple base.apk base.dm
Jetpack ProfileInstaller
在搭載 API 級別 29 以上版本的裝置上,Jetpack ProfileInstaller 程式庫提供了另一種機制,可在 APK 安裝到裝置上後,「安裝」封裝至 assets
或 dexopt
中的設定檔。ProfileInstaller
是由 ProfileInstallReceiver
或應用程式直接叫用。
ProfileInstaller 程式庫會根據目標裝置的 SDK 版本對設定檔進行轉碼,並將設定檔複製到裝置上的 cur
目錄 (裝置上 ART 設定檔的套件專屬暫存目錄)。
一旦裝置處於閒置狀態,裝置上名為 bg-dexopt
的程序就會編譯設定檔。
側載基準設定檔
本節說明如何在具備 APK 的情況下安裝基準設定檔。
使用 androidx.profileinstaller
播送
在搭載 API 24 以上版本的裝置上,您可以播送指令來安裝設定檔:
# 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>
大多數包含基準設定檔的 APK 中都沒有 ProfileInstaller (Play 中有約 45 萬個應用程式,其中約 7.7 萬個應用程式有 ProfileInstaller),但其實每個使用 Compose 的 APK 中都有 ProfileInstaller。這是因為程式庫可提供設定檔,而不必宣告 ProfileInstaller 的依附元件。從 Jetpack 開始,每個有設定檔的程式庫都會新增依附元件。
將 install-multiple
與 Profgen 或 DexMetaData 搭配使用
在搭載 API 28 以上版本的裝置上,您不必在應用程式中安裝 ProfileInstaller 程式庫,就可以在應用程式中側載基準設定檔。
方法是使用 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
如要支援 APK 分割功能,請分別為每個 APK 執行一次上述的擷取設定檔步驟。安裝時請傳遞每個 APK 和相關聯的 .dm
檔案,確保 APK 和 .dm
名稱相符:
adb install-multiple appname-base.apk appname-base.dm \
appname-split1.apk appname-split1.dm
驗證
如要驗證是否已正確安裝設定檔,請按照「手動評估應用程式改善情形」中的步驟操作。
傾印二進位設定檔的內容
如果想要自我檢查基準設定檔的精簡二進位檔版本內容,請使用 Profgen-cli dumpProfile
選項:
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
需要 APK,因為精簡二進位檔表示法只會儲存 DEX 偏移,因此需要重新建構類別和方法名稱。
根據預設,系統會啟用嚴格模式,對 APK 中 DEX 檔案進行設定檔相容性檢查。如果您嘗試對其他工具產生的設定檔進行偵錯,可能會發生相容性錯誤,導致您無法傾印檔案以供調查。在這種情況下,您可以使用 --strict false
停用嚴格模式。但在大部分情況下,應保持啟用嚴格模式。
您可以選用模糊處理對應,此模式可將模糊處理的符號重新對應到人類可讀的版本,以便使用。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 提升 SQLite 效能的最佳做法
- 基準設定檔 {:#baseline-profiles}
- 部分 Wake Lock 停滯