اکیداً توصیه میکنیم برای کاهش تلاش دستی و افزایش مقیاسپذیری عمومی، تولید قوانین نمایه را بااستفاده از کتابخانه Jetpack Macrobenchmark خودکار کنید. بااینحال، امکان ایجاد و اندازهگیری دستی قوانین نمایه در برنامهتان وجود دارد.
تعریف دستی قوانین نمایه
میتوانید با ایجاد فایلی بهنام baseline-prof.txt در دایرکتوری src/main، قوانین نمایه را بهصورت دستی در یک برنامه یا ماژول کتابخانه تعریف کنید. این همان پوشهای است که حاوی فایل AndroidManifest.xml است.
این فایل در هر خط یک قانون را مشخص میکند. هر قانون نشاندهنده الگویی برای تطبیق روشها یا کلاسها در برنامه یا کتابخانهای است که باید بهینهسازی شود.
نحو این قوانین هنگام استفاده از adb shell profman --dump-classes-and-methods، یک اَبَرمجموعه از قالب نمایه ART قابلخواندن برای انسان (HRF) است. نحو
شبیه به نحو برای توصیفکنندهها و
امضاها است، اما اجازه میدهد
از نویسههای عام برای ساده کردن فرایند نوشتن قانون استفاده شود.
مثال زیر چند قانون Baseline Profile را نشان میدهد که در کتابخانه 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»، به افزونه نمایههای خط پایه Android مراجعه کنید.
نمونهای از قانون نویسه عام ممکن است چیزی شبیه به این باشد:
HSPLandroidx/compose/ui/layout/**->**(**)**
انواع پشتیبانیشده در قوانین «نمایه مبنا»
قوانین «نمایه پایه» از انواع زیر پشتیبانی میکند. برای جزئیات مربوط به این نوعها، قالب Dalvik Executable (DEX) را ببینید.
| نویسه | نوع | شرح |
|---|---|---|
B |
بایت | بایت علامتدار |
C |
char | نقطه کد نویسه یونیکد کدبندیشده در UTF-16 |
D |
دو نفره | مقدار نقطه شناور با دقت مضاعف |
F |
شناور | مقدار نقطه شناور با دقت تکی |
I |
قطع توپ | عدد صحیح |
J |
طولانی | عدد صحیح طولانی |
S |
فیلم کوتاه | کوتهویدیو امضاشده |
V |
باطل کردن | باطل کردن |
Z |
بولی | درست یا غلط |
L (نام کلاس) |
مرجع | نمونهای از نام کلاس |
بهعلاوه، کتابخانهها میتوانند قوانینی را تعریف کنند که در مصنوعات AAR بستهبندی شدهاند. وقتی APK میسازید تا این آرتیفکتها را دربرگیرد، قوانین باهم ادغام میشوند (مشابه نحوه ادغام مانیفست) و در نمایه ART دودویی فشردهای که مختص APK است کامپایل میشوند.
وقتی از APK در دستگاهها استفاده میشود، ART از این نمایه برای کامپایل کردن AOT
زیرمجموعه خاصی از برنامه در زمان نصب در Android نسخه ۹ (سطح API ۲۸)
یا Android نسخه ۷ (سطح API ۲۴) هنگام استفاده از
ProfileInstaller استفاده میکند.
جمعآوری دستی Baseline Profiles
میتوانید بدون راهاندازی کتابخانه Macrobenchmark، بهطور دستی «نمایه پایه» تولید کنید و خودکارسازیهای میانای کاربر را برای مسیرهای قطعی کاربر ایجاد کنید. اگرچه استفاده از Macrobenchmarks را توصیه میکنیم، اما ممکن است همیشه امکانپذیر نباشد. برای مثال، اگر از سیستم ساخت غیرGradle استفاده میکنید، نمیتوانید از افزونه Gradle «نمایه پایه» استفاده کنید. در این موارد، میتوانید قوانین Baseline Profile را بهصورت دستی جمعآوری کنید. اگر از دستگاه یا شبیهساز دارای میانای برنامهسازی کاربردی ۳۴ و بالاتر استفاده کنید، این کار بسیار آسانتر است. اگرچه این کار هنوز با سطوح پایینتر API امکانپذیر است، اما به دسترسی ریشه نیاز دارد و باید از شبیهسازی استفاده کنید که تصویر AOSP را اجرا میکند. میتوانید قوانین را مستقیماً با انجام کارهای زیر جمعآوری کنید:
- نسخه پخش برنامهتان را در دستگاه آزمایشی نصب کنید. نوع ساخت برنامه نباید با R8 بهینهسازی شده باشد و نباید قابلاشکالزدایی باشد تا بتواند نمایهای را ضبط کند که سیستم ساخت بتواند از آن استفاده کند.
- نصب نمایه را غیرفعال کنید و برنامه را ببندید.
اگر APK شما به کتابخانه Profile Installer Jetpack وابسته باشد، کتابخانه در اولین راهاندازی APK شما، نمایهای را راهاندازی میکند. این امر میتواند در فرایند تولید نمایه تداخل ایجاد کند، بنابراین آن را با فرمان زیر غیرفعال کنید:
adb shell am broadcast -a androidx.profileinstaller.action.SKIP_FILE WRITE_SKIP_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
بازنشانی کردن کامپایل برنامه و پاک کردن همه نمایهها.
API 34 و بالاتر
adb shell cmd package compile -f -m verify $PACKAGE_NAME adb shell pm art clear-app-profiles $PACKAGE_NAME
میانای برنامهسازی کاربردی ۳۳ و پایینتر
adb root adb shell cmd package compile --reset $PACKAGE_NAME
برنامه را اجرا کنید و بهصورت دستی در مسیرهای قطعی کاربر که میخواهید برای آنها نمایه جمعآوری کنید پیمایش کنید.
حداقل پنج ثانیه صبر کنید تا نمایهها تثبیت شوند.
عمل ذخیره را انجام دهید و منتظر بمانید تا ذخیره تکمیل شود. اگر APK شما به کتابخانه Jetpack Profile Installer وابسته است، از آن برای تخلیه نمایهها استفاده کنید:
اگر از Profile Installer استفاده نمیکنید، نمایهها را بهصورت دستی در شبیهساز بااستفاده از فرمان زیر تخلیه کنید: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
adb root adb shell killall -s SIGUSR1 $PACKAGE_NAME sleep 1 # wait 1 second adb shell am force-stop $PACKAGE_NAME
نمایههای دودویی تولیدشده را به نوشتار تبدیل کنید:
API 34 و بالاتر
adb shell pm dump-profiles --dump-classes-and-methods $PACKAGE_NAME
میانای برنامهسازی کاربردی ۳۳ و پایینتر
تعیین کنید که آیا نمایه مرجع یا نمایه فعلی ایجاد شده است یا نه. نمایه مرجع در مکان زیر قرار دارد:
/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/
این کار قوانین نمایه تولیدشده را میکشد و آنها را در واحد برنامه شما نصب میکند. دفعه بعد که برنامه را میسازید، Baseline Profile اضافه میشود. با دنبال کردن مراحل موجود در مشکلات نصب، این موضوع را تأیید کنید.
سنجش دستی بهبودهای برنامه
اکیداً توصیه میکنیم که بهبودهای برنامه را ازطریق محکزنی بسنجید. بااینحال، اگر میخواهید بهبودها را بهصورت دستی اندازهگیری کنید، میتوانید با اندازهگیری راهاندازی برنامه بهینهسازینشده بهعنوان مرجع شروع کنید.
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 کمک میکند تا بتوان آنها را بدون درنظر گرفتن نسخه کیت توسعه نرمافزار هدف در دستگاههای مجهز به Android نصب کرد.
Profgen-cli یک CLI است که HRF یک «نمایه مبنا» را به قالب کامپایلشده آن کامپایل میکند. رابط خط فرمان همچنین در مخزن cmdline-tools بهعنوان بخشی از کیت توسعه نرمافزار Android ارسال میشود.
این ویژگیها در شاخه 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 و
نقشه مبهمسازی نیاز دارد که برای مبهمسازی APK هنگام
استفاده از R8 یا Proguard استفاده میشود. بهاینترتیب، 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 را در پوشه
assets یا dexopt در APK کپی کنید.
نقشههای مبهمسازی کد
فقط درصورتی باید نقشه مبهمسازی را ارائه دهید که HRF از نمادهای منبع استفاده کند. اگر
HRF از ساخت نسخه پخشی تولید شده است که قبلاً مبهمسازی شده است و
نیازی به نگاشت نیست، میتوانید آن گزینه را نادیده بگیرید و خروجیها را در پوشه
assets یا dexopt کپی کنید.
نصب سنتی Baseline Profiles
«نمایههای مبنا» معمولاً به یکی از دو روش زیر به دستگاه ارسال میشوند.
استفاده کردن از install-multiple با DexMetadata
در دستگاههایی که API 28 و بالاتر را اجرا میکنند، کلاینت Play فایل APK و بار DexMetadata (DM) را برای نسخه APK درحال نصب بارگیری میکند. DM حاوی اطلاعات نمایهای است که به «مدیر بسته» در دستگاه منتقل میشود.
APK و DM بهعنوان بخشی از یک جلسه نصب تکی بااستفاده از چیزی مثل این نصب میشوند:
adb install-multiple base.apk base.dm
Jetpack ProfileInstaller
در دستگاههایی که سطح API ۲۹ و بالاتر را اجرا میکنند، کتابخانه Jetpack
ProfileInstaller سازوکار جایگزینی برای نصب نمایهای که در assetsیا dexopt بستهبندی شده است پساز نصب APK در دستگاه ارائه میدهد. ProfileInstaller توسط
ProfileInstallReceiver یا مستقیماً توسط برنامه فراخوانی میشود.
کتابخانه ProfileInstaller نمایه را براساس نسخه کیت توسعه نرمافزار دستگاه هدف تراتبدیل میکند و نمایه را در دایرکتوری cur در دستگاه (یک دایرکتوری آمادهسازی مختص بسته برای نمایههای ART در دستگاه) کپی میکند.
وقتی دستگاه غیرفعال است، نمایه توسط فرایندی بهنام
bg-dexopt در دستگاه انتخاب میشود.
بارگذاری جانبی «نمایه مبنا»
این بخش نحوه نصب Baseline Profile را با داشتن 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های دارای «نمایههای پایه» وجود ندارد—که در حدود ۷۷ هزار از ۴۵۰ هزار برنامه در Play وجود دارد—هرچند در عمل در هر APK که از Compose استفاده میکند وجود دارد. دلیلش این است که کتابخانهها میتوانند بدون اعلام وابستگی به ProfileInstaller، نمایه ارائه دهند. افزودن وابستگی در هر کتابخانه با نمایه از Jetpack شروع میشود.
استفاده از install-multiple با profgen یا DexMetaData
در دستگاههایی که میانای برنامهسازی کاربردی ۲۸ و بالاتر را اجرا میکنند، میتوانید «نمایه پایه» را بدون نیاز به داشتن کتابخانه 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}
- قفلهای بیداری جزئی گیرکرده