برای کاهش تلاش دستی و افزایش مقیاس پذیری عمومی، ما به شدت توصیه می کنیم که قوانین پروفایل را به صورت خودکار با استفاده از کتابخانه Jetpack Macrobenchmark تولید کنید. با این حال، این امکان وجود دارد که به صورت دستی قوانین نمایه را در برنامه خود ایجاد و اندازه گیری کنید.
قوانین پروفایل را به صورت دستی تعریف کنید
با ایجاد فایلی به نام baseline-prof.txt
که در دایرکتوری src/main
قرار دارد، می توانید قوانین نمایه را به صورت دستی در یک برنامه یا یک ماژول کتابخانه تعریف کنید. این همان پوشه ای است که حاوی فایل AndroidManifest.xml
است.
فایل در هر خط یک قانون را مشخص می کند. هر قانون نشان دهنده الگویی برای تطبیق روش ها یا کلاس ها در برنامه یا کتابخانه است که باید بهینه شود.
سینتکس این قوانین یک ابرمجموعه از فرمت نمایه ART قابل خواندن برای انسان (HRF) هنگام استفاده از adb shell profman --dump-classes-and-methods
است. نحو شبیه به نحو برای توصیفگرها و امضاها است، اما اجازه می دهد تا از حروف عام برای ساده کردن فرآیند نوشتن قانون استفاده شود.
مثال زیر چند قانون نمایه پایه موجود در کتابخانه 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; . L در اینجا با فرمت Dalvik Executable (DEX) اضافه شده است. |
METHOD_SIGNATURE | امضای متد، شامل نام، انواع پارامترها و انواع برگشتی متد. به عنوان مثال:// LayoutNode.kt fun isPlaced():Boolean { // ... } در LayoutNode دارای امضای isPlaced()Z است. |
این الگوها می توانند دارای حروف عام باشند تا یک قانون واحد شامل چندین روش یا کلاس باشد. برای راهنمایی راهنمایی هنگام نوشتن با نحو قوانین در Android Studio، به افزونه Android Baseline Profiles مراجعه کنید.
یک مثال از یک قانون عام ممکن است چیزی شبیه به این باشد:
HSPLandroidx/compose/ui/layout/**->**(**)**
انواع پشتیبانی شده در قوانین نمایه پایه
قوانین نمایه پایه از انواع زیر پشتیبانی می کنند. برای جزئیات بیشتر در مورد این انواع، به فرمت Dalvik Executable (DEX) مراجعه کنید.
شخصیت | تایپ کنید | توضیحات |
---|---|---|
B | بایت | بایت امضا شده |
C | کاراکتر | نقطه کد کاراکتر یونیکد کدگذاری شده در UTF-16 |
D | دو برابر کردن | مقدار ممیز شناور با دقت دو برابر |
F | شناور | مقدار ممیز شناور تک دقیق |
I | بین المللی | عدد صحیح |
J | طولانی | عدد صحیح بلند |
S | کوتاه | امضا کوتاه |
V | باطل | باطل |
Z | بولی | درست یا نادرست |
L (نام کلاس) | مرجع | نمونه ای از نام کلاس |
علاوه بر این، کتابخانه ها می توانند قوانینی را تعریف کنند که در آرتیفکت های AAR بسته بندی شده اند. وقتی یک APK برای گنجاندن این مصنوعات میسازید، قوانین با هم ادغام میشوند - مشابه نحوه انجام ادغام مانیفست - و در یک نمایه ART باینری فشرده که مخصوص APK است، کامپایل میشوند.
وقتی از APK در دستگاهها استفاده میشود، ART از این نمایه استفاده میکند تا AOT زیرمجموعه خاصی از برنامه را در زمان نصب در Android 9 (سطح API 28) یا Android 7 (سطح API 24) هنگام استفاده از ProfileInstaller
کامپایل کند.
پروفایل های پایه را به صورت دستی جمع آوری کنید
میتوانید بدون راهاندازی کتابخانه Macrobenchmark به صورت دستی یک نمایه خط پایه ایجاد کنید و اتوماسیونهای رابط کاربری سفرهای کاربر مهم خود را ایجاد کنید. اگرچه توصیه می کنیم از Macrobenchmarks استفاده کنید، اما ممکن است همیشه امکان پذیر نباشد. به عنوان مثال، اگر از یک سیستم ساخت غیر Gradle استفاده می کنید، نمی توانید از پلاگین Baseline Profile Gradle استفاده کنید. در چنین مواردی، می توانید قوانین نمایه پایه را به صورت دستی جمع آوری کنید. اگر از دستگاه یا شبیهساز دارای API 34 و بالاتر استفاده میکنید، این کار بسیار آسانتر است. اگرچه هنوز با سطوح API پایین تر امکان پذیر است، اما نیاز به دسترسی ریشه دارد و شما باید از یک شبیه ساز استفاده کنید که یک تصویر 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 وابستگی دارد، از آن برای حذف نمایه ها استفاده کنید:
اگر از 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 همچنین در مخزن cmdline-tools
به عنوان بخشی از Android SDK ارسال می شود.
این ویژگی ها در شعبه 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
آرگومان اول نشان دهنده مسیر HRF baseline-prof.txt
است.
Profgen-cli همچنین به مسیر انتشار APK و یک نقشه مبهم سازی نیاز دارد که برای مبهم کردن APK هنگام استفاده از R8 یا Proguard استفاده می شود. به این ترتیب، profgen
می تواند نمادهای منبع در HRF را به نام های مبهم متناظر آنها در هنگام ساختن نمایه کامپایل شده ترجمه کند.
از آنجایی که فرمتهای نمایههای ART سازگار با جلو یا عقب نیستند، یک قالب نمایه ارائه کنید تا profgen
متادادههای پروفایل ( profm
) را بستهبندی کند که در صورت لزوم بتوانید از آن برای تبدیل یک قالب نمایه ART به دیگری در صورت لزوم استفاده کنید.
فرمت های پروفایل و نسخه های پلتفرم
هنگام انتخاب فرمت نمایه گزینه های زیر در دسترس هستند:
فرمت نمایه | نسخه پلتفرم | سطح API |
---|---|---|
v0_1_5_s | اندروید S+ | 31+ |
v0_1_0_p | اندروید پی، کیو و آر | 28-30 |
v0_0_9_omr1 | اندروید O MR1 | 27 |
v0_0_5_o | اندروید O | 26 |
v0_0_1_n | اندروید N | 24-25 |
فایل های خروجی baseline.prof
و baseline.profm
را در پوشه assets
یا dexopt
در APK کپی کنید.
نقشه های مبهم سازی
اگر HRF از نمادهای منبع استفاده می کند، فقط باید نقشه مبهم سازی را ارائه دهید. اگر HRF از یک نسخه منتشر شده تولید شده است که قبلاً مبهم است و نیازی به نقشه برداری نیست، می توانید آن گزینه را نادیده بگیرید و خروجی ها را در پوشه assets
یا dexopt
کپی کنید.
نصب سنتی پروفایل های پایه
نمایه های خط پایه به طور سنتی به یکی از دو روش به دستگاه تحویل داده می شوند.
از install-multiple
با DexMetadata استفاده کنید
در دستگاههای دارای API 28 و بالاتر، کلاینت Play فایل APK و DexMetadata (DM) را برای نسخه APK در حال نصب دانلود میکند. DM حاوی اطلاعات نمایه است که در دستگاه به Package Manager ارسال می شود.
APK و DM به عنوان بخشی از یک جلسه نصب با استفاده از موارد زیر نصب می شوند:
adb install-multiple base.apk base.dm
Jetpack ProfileInstaller
در دستگاههای دارای API سطح 29 و بالاتر، کتابخانه Jetpack ProfileInstaller مکانیزم جایگزینی برای نصب نمایه بستهبندی شده در assets
یا dexopt
پس از نصب APK در دستگاه ارائه میکند. ProfileInstaller
توسط ProfileInstallReceiver
یا مستقیماً توسط برنامه فراخوانی می شود.
کتابخانه ProfileInstaller نمایه را بر اساس نسخه SDK دستگاه مورد نظر رمزگذاری میکند و نمایه را در فهرست cur
روی دستگاه کپی میکند.
هنگامی که دستگاه بیکار است، نمایه توسط فرآیندی به نام 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>
ProfileInstaller در اکثر فایلهای APK با نمایههای پایه - که در حدود 77 هزار برنامه از 450 هزار برنامه در Play وجود دارد - وجود ندارد - اگرچه به طور مؤثر در هر APK با استفاده از Compose وجود دارد. این به این دلیل است که کتابخانه ها می توانند پروفایل ها را بدون اعلام وابستگی به 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 را ذخیره می کند و بنابراین برای بازسازی نام کلاس ها و روش ها به آنها نیاز دارد.
حالت سختگیرانه به طور پیش فرض فعال است، و این یک بررسی سازگاری نمایه با فایل های DEX در APK را انجام می دهد. اگر میخواهید نمایههایی را که توسط ابزار دیگری تولید شدهاند را اشکالزدایی کنید، ممکن است با نقصهای سازگاری مواجه شوید که نتوانید آن را برای بررسی رها کنید. در چنین مواردی، می توانید حالت سخت را با --strict false
غیرفعال کنید. با این حال، در بیشتر موارد باید حالت سخت را فعال نگه دارید.
نقشه مبهم اختیاری است. در صورت ارائه، به بازنگری نمادهای مبهم به نسخه های قابل خواندن توسط انسان برای سهولت استفاده کمک می کند.
{% کلمه به کلمه %}برای شما توصیه می شود
- توجه: متن پیوند زمانی که جاوا اسکریپت خاموش است نمایش داده می شود
- بهترین روش ها برای عملکرد SQLite
- نمایه های پایه {:#baseline-profiles}
- ویک لاک های جزئی گیر کرده است