ما اکیداً توصیه میکنیم که با استفاده از کتابخانه Jetpack Macrobenchmark، تولید خودکار قوانین پروفایل را انجام دهید تا از حجم کار دستی کاسته و مقیاسپذیری عمومی افزایش یابد. با این حال، ایجاد و اندازهگیری دستی قوانین پروفایل در برنامه شما امکانپذیر است.
تعریف دستی قوانین پروفایل
شما میتوانید با ایجاد فایلی به نام baseline-prof.txt که در دایرکتوری src/main قرار دارد، قوانین پروفایل را به صورت دستی در یک برنامه یا یک ماژول کتابخانه تعریف کنید. این همان پوشهای است که فایل AndroidManifest.xml در آن قرار دارد.
این فایل در هر خط یک قانون را مشخص میکند. هر قانون، الگویی را برای تطبیق متدها یا کلاسها در برنامه یا کتابخانهای که نیاز به بهینهسازی دارد، نشان میدهد.
نحو این قوانین، مجموعهای از قالب پروفایل ART (HRF) قابل خواندن توسط انسان هنگام استفاده از adb shell profman --dump-classes-and-methods است. این نحو مشابه نحو توصیفکنندهها و امضاها است، اما اجازه میدهد تا از کاراکترهای جایگزین (wildcards) برای سادهسازی فرآیند نوشتن قانون استفاده شود.
مثال زیر چند قانون پروفایل پایه موجود در کتابخانه 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) که توسط انسان قابل خواندن است پشتیبانی میکند، بنابراین از wildcardها پشتیبانی نمیشود.
نحو قاعده
این قوانین برای هدف قرار دادن متدها یا کلاسها، یکی از دو شکل زیر را به خود میگیرند:
[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.ktfun isPlaced():Boolean {// ...}در LayoutNode امضای isPlaced()Z را دارد. |
این الگوها میتوانند دارای wildcard باشند تا یک قانون واحد شامل چندین متد یا کلاس باشد. برای راهنمایی هنگام نوشتن با سینتکس قانون در اندروید استودیو، به افزونه Android Baseline Profiles مراجعه کنید.
یک مثال از قانون wildcard میتواند چیزی شبیه به این باشد:
HSPLandroidx/compose/ui/layout/**->**(**)**
انواع پشتیبانی شده در قوانین نمایه پایه
قوانین پروفایل پایه از انواع زیر پشتیبانی میکنند. برای جزئیات بیشتر در مورد این نوعها، به فرمت Dalvik Executable (DEX) مراجعه کنید.
| شخصیت | نوع | توضیحات |
|---|---|---|
B | بایت | بایت امضا شده |
C | کاراکتر | نقطه کد کاراکتر یونیکد در UTF-16 کدگذاری شده است |
D | دو برابر | مقدار ممیز شناور با دقت مضاعف |
F | شناور | مقدار ممیز شناور با دقت تکی |
I | عدد صحیح | عدد صحیح |
J | طولانی | عدد صحیح بلند |
S | کوتاه | کوتاه امضا شده |
V | باطل | باطل |
Z | بولی | درست یا غلط |
L (نام کلاس) | مرجع | نمونهای از نام کلاس |
علاوه بر این، کتابخانهها میتوانند قوانینی را تعریف کنند که در مصنوعات AAR بستهبندی شدهاند. وقتی یک APK برای گنجاندن این مصنوعات میسازید، قوانین با هم ادغام میشوند - مشابه نحوه ادغام مانیفست - و در یک پروفایل ART باینری فشرده که مختص APK است، کامپایل میشوند.
ART از این پروفایل زمانی که APK روی دستگاهها استفاده میشود، برای کامپایل AOT زیرمجموعه خاصی از برنامه در زمان نصب در اندروید ۹ (سطح API ۲۸) یا اندروید ۷ (سطح API ۲۴) هنگام استفاده از ProfileInstaller استفاده میکند.
جمعآوری دستی پروفایلهای پایه
شما میتوانید بدون تنظیم کتابخانه Macrobenchmark، یک Baseline Profile به صورت دستی ایجاد کنید و UI خودکاری از مسیرهای حیاتی کاربر خود ایجاد کنید. اگرچه ما استفاده از Macrobenchmarks را توصیه میکنیم، اما ممکن است همیشه امکانپذیر نباشد. به عنوان مثال، اگر از یک سیستم ساخت غیر Gradle استفاده میکنید، نمیتوانید از افزونه Baseline Profile Gradle استفاده کنید. در چنین مواردی، میتوانید به صورت دستی قوانین Baseline Profile را جمعآوری کنید. اگر از دستگاه یا شبیهساز با API 34 و بالاتر استفاده میکنید، این کار بسیار آسانتر است. اگرچه هنوز هم با سطوح API پایینتر امکانپذیر است، اما به دسترسی روت نیاز دارد و باید از یک شبیهساز با اجرای یک تصویر AOSP استفاده کنید. میتوانید با انجام موارد زیر، قوانین را مستقیماً جمعآوری کنید:
- یک نسخه آزمایشی از برنامه خود را روی یک دستگاه آزمایشی نصب کنید. نوع ساخت برنامه نباید برای R8 بهینه شده باشد و نباید قابل اشکالزدایی باشد تا بتواند پروفایلی را که میتواند توسط سیستم ساخت استفاده شود، ثبت کند.
- نصب پروفایل را غیرفعال کنید و برنامه را ببندید.
اگر APK شما به کتابخانه Jetpack Profile Installer وابسته باشد، این کتابخانه در اولین اجرای 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
API 33 و پایینتر
adb root adb shell cmd package compile --reset $PACKAGE_NAME
برنامه را اجرا کنید و به صورت دستی در مسیرهای کاربری حیاتی که میخواهید برای آنها پروفایل جمعآوری کنید، پیمایش کنید.
حداقل پنج ثانیه صبر کنید تا پروفایلها تثبیت شوند.
عمل ذخیره را انجام دهید و منتظر بمانید تا ذخیره کامل شود. اگر APK شما به کتابخانه Jetpack 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
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برای بازیابی پروفایل dump شده از دستگاه استفاده کنید: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 هنگام ساخت یک نسخه دودویی فشرده از یک Baseline Profile چه کاری انجام میدهد.
Profgen-cli به کامپایل پروفایل، دروننگری و انتقال پروفایلهای ART کمک میکند، بنابراین میتوان آنها را صرف نظر از نسخه SDK هدف، روی دستگاههای دارای اندروید نصب کرد.
Profgen-cli یک رابط خط فرمان (CLI) است که HRF یک پروفایل پایه (Baseline Profile) را به فرمت کامپایل شده آن کامپایل میکند. این رابط خط فرمان همچنین به عنوان بخشی از 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 و یک نقشه مبهمسازی که برای مبهمسازی APK هنگام استفاده از R8 یا Proguard استفاده میشود، نیاز دارد. به این ترتیب، profgen میتواند نمادهای منبع در HRF را هنگام ساخت پروفایل کامپایلشده به نامهای مبهمسازیشده مربوطه ترجمه کند.
از آنجا که قالبهای پروفایلهای ART با نسخههای قبلی یا بعدی سازگار نیستند، یک قالب پروفایل ارائه دهید تا profgen فراداده پروفایل ( profm ) را بستهبندی کند که بتوانید در صورت لزوم برای تبدیل کد یک قالب پروفایل ART به قالب دیگر از آن استفاده کنید.
قالبهای پروفایل و نسخههای پلتفرم
هنگام انتخاب قالب پروفایل، گزینههای زیر در دسترس هستند:
| قالب پروفایل | نسخه پلتفرم | سطح API |
|---|---|---|
| v0_1_5_s | اندروید اس پلاس | ۳۱+ |
| v0_1_0_p | اندروید P، Q و R | ۲۸-۳۰ |
| v0_0_9_omr1 | اندروید O MR1 | ۲۷ |
| v0_0_5_o | اندروید O | ۲۶ |
| v0_0_1_n | اندروید N | ۲۴-۲۵ |
فایلهای خروجی 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
نصبکننده پروفایل جتپک
در دستگاههایی که API سطح ۲۹ و بالاتر را اجرا میکنند، کتابخانه Jetpack ProfileInstaller یک مکانیسم جایگزین برای نصب یک پروفایل بستهبندی شده در assets یا dexopt پس از نصب APK روی دستگاه ارائه میدهد. 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>
ProfileInstaller در اکثر APKهایی که از Baseline Profiles استفاده میکنند - که در حدود ۷۷ هزار از ۴۵۰ هزار برنامه در Play وجود دارد - وجود ندارد، اگرچه عملاً در هر APK که از Compose استفاده میکند، وجود دارد. دلیل این امر این است که کتابخانهها میتوانند پروفایلها را بدون اعلام وابستگی به ProfileInstaller ارائه دهند. افزودن وابستگی در هر کتابخانهای که دارای پروفایل است، از Jetpack شروع میشود.
از install-multiple به همراه profgen یا DexMetaData استفاده کنید
در دستگاههایی که API 28 و بالاتر را اجرا میکنند، میتوانید بدون نیاز به داشتن کتابخانه ProfileInstaller در برنامه، یک Baseline Profile را از طریق Sideload نصب کنید.
برای این کار، از 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
تأیید
برای تأیید نصب صحیح پروفایل، میتوانید از مراحل موجود در «اندازهگیری دستی بهبودهای برنامه» استفاده کنید.
محتویات یک پروفایل دودویی را تخلیه کنید
برای بررسی محتویات یک نسخه باینری فشرده از یک Baseline Profile، از گزینه 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 را ذخیره میکند و بنابراین، برای بازسازی نام کلاسها و متدها به آنها نیاز دارد.
حالت سختگیرانه (Strict mode) به طور پیشفرض فعال است و این حالت، سازگاری پروفایل را با فایلهای DEX در APK بررسی میکند. اگر سعی دارید پروفایلهایی را که توسط ابزار دیگری ایجاد شدهاند، اشکالزدایی کنید، ممکن است با خطاهای سازگاری مواجه شوید که مانع از امکان بررسی و ارسال فایلها میشود. در چنین مواردی، میتوانید حالت سختگیرانه را با استفاده از --strict false غیرفعال کنید. با این حال، در بیشتر موارد، باید حالت سختگیرانه را فعال نگه دارید.
نقشه مبهمسازی اختیاری است؛ در صورت ارائه، به نگاشت مجدد نمادهای مبهمسازی شده به نسخههای قابل خواندن توسط انسان برای سهولت استفاده کمک میکند.
{% کلمه به کلمه %}برای شما توصیه میشود
- توجه: متن لینک زمانی نمایش داده میشود که جاوا اسکریپت غیرفعال باشد.
- بهترین شیوهها برای عملکرد SQLite
- پروفایلهای پایه {:#baseline-profiles}
- قفلهای بیداری جزئی گیر کردهاند