إنشاء الملفات المرجعية الأساسية وقياسها يدويًا

ننصحك بشدة بتفعيل إنشاء قواعد الملفات الشخصية تلقائيًا باستخدام مكتبة قياس الأداء على مستوى التطبيق في Jetpack للحدّ من المجهود اليدوي وزيادة قابلية التوسّع العامة. ومع ذلك، من الممكن إنشاء قواعد الملفات الشخصية وقياسها يدويًا في تطبيقك.

تحديد قواعد الملف التجاري يدويًا

يمكنك تحديد قواعد الملف الشخصي يدويًا في تطبيق أو وحدة مكتبة عن طريق إنشاءملف باسم baseline-prof.txt في الدليل src/main. هذا هو المجلد نفسه الذي يحتوي على ملف AndroidManifest.xml.

يحدّد الملف قاعدة واحدة في كل سطر. تمثّل كل قاعدة نمطًا لمحاولة مطابقة الطرق أو الفئات في التطبيق أو المكتبة التي يجب تحسينها.

بنية هذه القواعد هي مجموعة فائقة من تنسيق الملف الشخصي ART القابل للقراءة (HRF) عند استخدام adb shell profman --dump-classes-and-methods. تتشابه بنية الوصف مع بنية الأوصاف والتوقيعات، ولكنها تتيح استخدام العناصر النائبة لتبسيط عملية كتابة القواعد.

يعرض المثال التالي بعض قواعد الملف الشخصي الأساسي المضمّنة في مكتبة Compose في Jetpack:

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 لا تتوافق إلا مع تنسيق الملف الشخصي لـ 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.

يمكن أن تحتوي هذه الأنماط على أحرف عشوائية لتشمل قاعدة واحدة عدة methods أو فئات. للحصول على مساعدة إرشادية عند الكتابة باستخدام بنية القواعد في IDE Android Studio، اطّلِع على المكوّن الإضافي ملفات Android Baseline Profile.

قد يبدو مثال على قاعدة العنصر النائب على النحو التالي:

HSPLandroidx/compose/ui/layout/**->**(**)**

الأنواع المتوافقة في قواعد الملف الشخصي للمرجع

تتيح قواعد الملف الشخصي الأساسي الأنواع التالية. لمعرفة التفاصيل عن هذه الأنواع، راجِع تنسيق ملف Dalvik القابل للتنفيذ (DEX).

حرف النوع الوصف
B بايت بايت موقَّع
C char قيمة موضع رمز حرف يونيكود بترميز UTF-16
D مزدوج قيمة عدد فاصل عائم بدقة مضاعفة
F عائم قيمة فاصل عائم بدقة واحدة
I تدخُّل دفاعي عدد صحيح
J طويلة عدد صحيح كبير
S فيديو قصير فيديو Shorts موقَّع
V غير صالح غير صالح
Z قيمة منطقية صواب أم خطأ
L (اسم الفئة) المرجع مثيل لاسم فئة

بالإضافة إلى ذلك، يمكن للمكتبات تحديد القواعد التي يتم تجميعها في عناصر AAR. عند إنشاء حزمة APK لتضمين هذه العناصر، يتم دمج القواعد معًا، تمامًا مثل طريقة دمج البيان، ويتم تجميعها لإنشاء ملف تعريف ART ثنائي مضغوط خاص بحزمة APK.

تستفيد أداة ART من هذا الملف الشخصي عند استخدام حزمة APK على الأجهزة لتجميع مجموعة فرعية محدّدة من التطبيق أثناء التثبيت باستخدام ميزة AOT على Android 9 (المستوى 28 لواجهة برمجة التطبيقات) أو Android 7 (المستوى 24 لواجهة برمجة التطبيقات) عند استخدام ProfileInstaller.

جمع الملفات الشخصية للمرجع يدويًا

يمكنك إنشاء ملف تعريف أساسي يدويًا بدون إعداد مكتبة Macrobenchmark وإنشاء عمليات التشغيل الآلي لواجهة المستخدم لرحلات المستخدمين المهمة. على الرغم من أنّنا ننصح باستخدام مقاييس الأداء الشاملة، قد لا يكون ذلك ممكنًا في بعض الأحيان. على سبيل المثال، إذا كنت تستخدم نظام إنشاء غير Gradle، لا يمكنك استخدام الإضافة Baseline Profile Gradle. في هذه الحالات، يمكنك جمع قواعد "الملف الشخصي" "أساس الأداء" يدويًا. سيكون هذا الإجراء أسهل بكثير إذا كنت تستخدم جهازًا أو محاكيًا يعمل بواجهة برمجة التطبيقات 34 والإصدارات الأحدث. على الرغم من أنّه لا يزال من الممكن إجراء ذلك مع مستويات واجهة برمجة تطبيقات أقل، إلا أنّ ذلك يتطلّب إذن الوصول إلى الجذر، ويجب استخدام محاكي يعمل بنظام التشغيل AOSP. يمكنك جمع القواعد مباشرةً من خلال تنفيذ ما يلي:

  1. ثبِّت إصدارًا علنيًا من تطبيقك على جهاز اختبار. يجب أن يكون نوع إصدار التطبيق محسّنًا باستخدام R8 وغير قابل لتصحيح الأخطاء للحصول على ملف تعريف دقيق.
  2. تأكَّد من أنّه لم يتم تجميع الملفات التجارية من قبل.

    المستوى 34 لواجهة برمجة التطبيقات والإصدارات الأحدث

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

    المستوى 33 لواجهة برمجة التطبيقات والإصدارات الأقدم

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

    إذا كانت حزمة APK تعتمد على مكتبة Profile Installer في Jetpack، تبدأ المكتبة عملية إعداد ملف التعريف عند تشغيل حزمة APK لأول مرة. يمكن أن يتداخل ذلك مع عملية إنشاء الملف الشخصي، لذا أوقِفه باستخدام العبارة التالية:

    adb shell am broadcast -a androidx.profileinstaller.action.SKIP_FILE $PACKAGE_NAME/androidx.profileinstaller.ProfileInstallReceiver
  3. شغِّل التطبيق وانتقِل يدويًا خلال رحلات المستخدِمين الأساسية التي تريد جمع ملف شخصي لها.
  4. اطلب من ART تفريغ الملفات الشخصية. إذا كانت حزمة APK تعتمد على مكتبة أداة تثبيت الملفات الشخصية في Jetpack، استخدِم هذه المكتبة لتفريغ الملفات الشخصية:

    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
  5. انتظِر خمس ثوانٍ على الأقل إلى أن تكتمل عملية إنشاء الملف الشخصي.
  6. حوِّل الملفات الشخصية الثنائية التي يتم إنشاؤها إلى نص:

    المستوى 34 لواجهة برمجة التطبيقات والإصدارات الأحدث

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

    المستوى 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

  7. استخدِم adb لاسترداد الملف الشخصي الذي تم تفريغه من الجهاز:

    adb pull /data/misc/profman/$PACKAGE_NAME-primary.prof.txt PATH_TO_APP_MODULE/src/main/

يؤدي ذلك إلى سحب قواعد الملف الشخصي التي تم إنشاؤها وتثبيتها في وحدة تطبيقك. في المرة التالية التي تُنشئ فيها التطبيق، يتم تضمين الملف الشخصي الأساسي. يمكنك التحقّق من ذلك من خلال اتّباع الخطوات الواردة في مشاكل التثبيت.

قياس تحسينات التطبيق يدويًا

ننصحك بشدة بقياس تحسينات التطبيق من خلال قياس الأداء. ومع ذلك، إذا كنت تريد قياس التحسينات يدويًا، يمكنك البدء من خلال measuring the unoptimized app startup كمرجع.

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 بغض النظر عن إصدار حزمة SDK المستهدَف.

‫Profgen-cli هو أداة سطر أوامر تُجمِّع ملف HRF الخاص بملف قياس الأداء الأساسي إلى تنسيقه المجمَّع. يتم أيضًا شحن واجهة برمجة التطبيقات (CLI) في مستودع cmdline-tools كجزء من IDE IDE لنظام التشغيل 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 إلى تنسيق آخر عند الحاجة.

تنسيقات الملفات الشخصية وإصدارات الأنظمة الأساسية

تتوفّر الخيارات التالية عند اختيار تنسيق الملف الشخصي:

تنسيق الملف الشخصي إصدار النظام الأساسي مستوى واجهة برمجة التطبيقات
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.

التثبيت التقليدي للملفات الشخصية للمرجع

يتم عادةً إرسال الملفات الشخصية الأساسية إلى الجهاز بطريقتَين.

استخدام install-multiple مع DexMetadata

على الأجهزة التي تعمل بالإصدار 28 من واجهة برمجة التطبيقات والإصدارات الأحدث، ينزِّل برنامج Play حِزمة APK وحمولة DexMetadata (DM) لإصدار APK الذي يتم تثبيته. يحتوي ملف البيانات الوصفية على معلومات الملف الشخصي التي يتم تمريرها إلى "مدير الحِزم" على الجهاز.

يتم تثبيت حزمة APK وملف البيان كجزء من جلسة تثبيت واحدة باستخدام الخطوات التالية على سبيل المثال:

adb install-multiple base.apk base.dm

Jetpack ProfileInstaller

على الأجهزة التي تعمل بالمستوى 29 من واجهة برمجة التطبيقات والإصدارات الأحدث، توفّر مكتبة Jetpack ProfileInstaller بديلاً لآلية تثبيت ملف شخصي تم حزمه في assetsأو dexopt بعد تثبيت APK على الجهاز. يتم استدعاء ProfileInstaller من قِبل ProfileInstallReceiver أو من قِبل التطبيق مباشرةً.

تُعيد مكتبة ProfileInstaller ترميز الملف الشخصي استنادًا إلى إصدار SDK الجهاز المستهدَف، وتنسخ الملف الشخصي إلى الدليل cur على الجهاز (وهو directory staging خاص بالحزمة لملفات ART الشخصية على الجهاز).

بعد أن يصبح الجهاز غير نشِط، يتم نقل ملف التعريف من خلال عملية تُعرف باسم bg-dexopt على الجهاز.

تحميل ملف مرجعي بشكل غير رسمي

يصف هذا القسم كيفية تثبيت ملف تعريف أساسي استنادًا إلى حزمة APK.

البث باستخدام androidx.profileinstaller

على الأجهزة التي تعمل بواجهة برمجة التطبيقات 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 Profile، والتي تتوفر في حوالي 77 ألف تطبيق من أصل 450 ألف تطبيق على Play، إلا أنّه يتوفّر بشكلٍ فعّال في كل حِزمة APK تستخدم Compose. ويعود السبب في ذلك إلى أنّ المكتبات يمكنها توفير الملفات التجارية بدون الإفصاح عن تبعية ProfileInstaller. تنطبق إضافة تبعية في كل مكتبة تضمّن ملفًا شخصيًا اعتبارًا من Jetpack.

استخدام install-multiple مع profgen أو DexMetaData

على الأجهزة التي تعمل بواجهة برمجة التطبيقات 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 لأنّ التمثيل الثنائي المكثّف يخزّن فقط Offsets DEX، وبالتالي يحتاج إليها لإعادة إنشاء أسماء الفئات والإجراءات.

يكون "الوضع الصارم" مفعَّلاً تلقائيًا، ويُجري هذا الفحص عملية تحقّق من توافقملف التكوين مع ملفات DEX في حزمة APK. إذا كنت تحاول تصحيح أخطاء الملفات الشخصية التي تم إنشاؤها بواسطة أداة أخرى، قد تواجه أخطاء في التوافق تمنع التمكن من تفريغها للتحقيق. في هذه الحالات، يمكنك إيقاف الوضع الصارم باستخدام --strict false. ومع ذلك، في معظم الحالات، يجب إبقاء الوضع المتشدد مفعّلاً.

خريطة التشويش اختيارية، وعند تقديمها، تساعد في إعادة ربط الرموز المشوشة بنسخها المفهومة للمستخدمين لتسهيل الاستخدام.