اشکال زدایی پروفایل های پایه

این سند بهترین شیوه‌ها و مراحل عیب‌یابی را برای کمک به تشخیص مشکلات و اطمینان از عملکرد صحیح پروفایل‌های پایه شما برای ارائه بیشترین مزایا ارائه می‌دهد.

مشکلات ساخت

اگر مثال Baseline Profiles را در برنامه نمونه Now in Android کپی کرده باشید، ممکن است در طول وظیفه Baseline Profile با خطای تست مواجه شوید که بیان می‌کند تست‌ها نمی‌توانند روی شبیه‌ساز اجرا شوند:

./gradlew assembleDemoRelease
Starting a Gradle Daemon (subsequent builds will be faster)
Calculating task graph as no configuration cache is available for tasks: assembleDemoRelease
Type-safe project accessors is an incubating feature.

> Task :benchmarks:pixel6Api33DemoNonMinifiedReleaseAndroidTest
Starting 14 tests on pixel6Api33

com.google.samples.apps.nowinandroid.foryou.ScrollForYouFeedBenchmark > scrollFeedCompilationNone[pixel6Api33] FAILED
        java.lang.AssertionError: ERRORS (not suppressed): EMULATOR
        WARNINGS (suppressed):
        ...

این خرابی‌ها به این دلیل رخ می‌دهند که Now in Android از یک دستگاه مدیریت‌شده توسط Gradle برای تولید Baseline Profile استفاده می‌کند. این خرابی‌ها قابل پیش‌بینی هستند، زیرا شما معمولاً نباید معیارهای عملکرد را روی یک شبیه‌ساز اجرا کنید. با این حال، از آنجایی که هنگام تولید Baseline Profiles معیارهای عملکرد را جمع‌آوری نمی‌کنید، می‌توانید برای راحتی، مجموعه Baseline Profile را روی شبیه‌سازها اجرا کنید. برای استفاده از Baseline Profiles با یک شبیه‌ساز، ساخت و نصب را از خط فرمان انجام دهید و یک آرگومان برای فعال کردن قوانین Baseline Profiles تنظیم کنید:

installDemoRelease -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile

از طرف دیگر، می‌توانید با انتخاب Run > Edit Configurations ، یک پیکربندی اجرای سفارشی در اندروید استودیو ایجاد کنید تا پروفایل‌های پایه را روی شبیه‌سازها فعال کنید:

برای ایجاد پروفایل‌های پایه در Now در اندروید، یک پیکربندی اجرای سفارشی اضافه کنید
شکل ۱. اضافه کردن یک پیکربندی اجرای سفارشی برای ایجاد پروفایل‌های پایه در Now در اندروید.

نصب و اجرای پروفایل را تأیید کنید

برای بررسی اینکه APK یا Android App Bundle (AAB) که بررسی می‌کنید از یک نسخه ساخت شامل Baseline Profiles است، موارد زیر را انجام دهید:

  1. در اندروید استودیو، گزینه Build > Analyze APK را انتخاب کنید.
  2. AAB یا APK خود را باز کنید.
  3. تأیید کنید که فایل baseline.prof وجود دارد:

    • اگر در حال بررسی یک AAB هستید، پروفایل آن در /BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof قرار دارد.
    • اگر در حال بررسی یک APK هستید، پروفایل آن در /assets/dexopt/baseline.prof قرار دارد.

      وجود این فایل اولین نشانه پیکربندی صحیح ساخت است. اگر وجود نداشته باشد، به این معنی است که Android Runtime هیچ دستورالعمل پیش از کامپایل را در زمان نصب دریافت نخواهد کرد.

      بررسی پروفایل پایه با استفاده از APK Analyzer در اندروید استودیو
      شکل ۲. بررسی پروفایل پایه با استفاده از APK Analyzer در اندروید استودیو

پروفایل‌های پایه باید روی دستگاهی که برنامه روی آن اجرا می‌شود، کامپایل شوند. وقتی نسخه‌های غیرقابل اشکال‌زدایی را با استفاده از اندروید استودیو یا ابزار خط فرمان Gradle wrapper نصب می‌کنید، کامپایل روی دستگاه به طور خودکار اتفاق می‌افتد. اگر برنامه را از فروشگاه گوگل پلی نصب کنید، پروفایل‌های پایه به جای زمان نصب، در حین به‌روزرسانی‌های پس‌زمینه دستگاه کامپایل می‌شوند. وقتی برنامه با استفاده از ابزارهای دیگر نصب می‌شود، کتابخانه Jetpack ProfileInstaller مسئول قرار دادن پروفایل‌ها برای کامپایل در طول فرآیند بهینه‌سازی DEX پس‌زمینه بعدی است.

در این موارد، اگر می‌خواهید مطمئن شوید که پروفایل‌های پایه شما استفاده می‌شوند، ممکن است لازم باشد کامپایل پروفایل‌های پایه را اجباری کنید . ProfileVerifier به شما امکان می‌دهد وضعیت نصب و کامپایل پروفایل را بررسی کنید، همانطور که در مثال زیر نشان داده شده است:

کاتلین

private const val TAG = "MainActivity"

class MainActivity : ComponentActivity() {
  ...
  override fun onResume() {
    super.onResume()
    lifecycleScope.launch {
      logCompilationStatus()
    }
  }

  private suspend fun logCompilationStatus() {
     withContext(Dispatchers.IO) {
        val status = ProfileVerifier.getCompilationStatusAsync().await()
        when (status.profileInstallResultCode) {
            RESULT_CODE_NO_PROFILE ->
                Log.d(TAG, "ProfileInstaller: Baseline Profile not found")
            RESULT_CODE_COMPILED_WITH_PROFILE ->
                Log.d(TAG, "ProfileInstaller: Compiled with profile")
            RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION ->
                Log.d(TAG, "ProfileInstaller: Enqueued for compilation")
            RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING ->
                Log.d(TAG, "ProfileInstaller: App was installed through Play store")
            RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST ->
                Log.d(TAG, "ProfileInstaller: PackageName not found")
            RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ ->
                Log.d(TAG, "ProfileInstaller: Cache file exists but cannot be read")
            RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE ->
                Log.d(TAG, "ProfileInstaller: Can't write cache file")
            RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION ->
                Log.d(TAG, "ProfileInstaller: Enqueued for compilation")
            else ->
                Log.d(TAG, "ProfileInstaller: Profile not compiled or enqueued")
        }
    }
}

جاوا

public class MainActivity extends ComponentActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onResume() {
        super.onResume();

        logCompilationStatus();
    }

    private void logCompilationStatus() {
         ListeningExecutorService service = MoreExecutors.listeningDecorator(
                Executors.newSingleThreadExecutor());
        ListenableFuture<ProfileVerifier.CompilationStatus> future =
                ProfileVerifier.getCompilationStatusAsync();
        Futures.addCallback(future, new FutureCallback<>() {
            @Override
            public void onSuccess(CompilationStatus result) {
                int resultCode = result.getProfileInstallResultCode();
                if (resultCode == RESULT_CODE_NO_PROFILE) {
                    Log.d(TAG, "ProfileInstaller: Baseline Profile not found");
                } else if (resultCode == RESULT_CODE_COMPILED_WITH_PROFILE) {
                    Log.d(TAG, "ProfileInstaller: Compiled with profile");
                } else if (resultCode == RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION) {
                    Log.d(TAG, "ProfileInstaller: Enqueued for compilation");
                } else if (resultCode == RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING) {
                    Log.d(TAG, "ProfileInstaller: App was installed through Play store");
                } else if (resultCode == RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST) {
                    Log.d(TAG, "ProfileInstaller: PackageName not found");
                } else if (resultCode == RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ) {
                    Log.d(TAG, "ProfileInstaller: Cache file exists but cannot be read");
                } else if (resultCode
                        == RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE) {
                    Log.d(TAG, "ProfileInstaller: Can't write cache file");
                } else if (resultCode == RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION) {
                    Log.d(TAG, "ProfileInstaller: Enqueued for compilation");
                } else {
                    Log.d(TAG, "ProfileInstaller: Profile not compiled or enqueued");
                }
            }

            @Override
            public void onFailure(Throwable t) {
                Log.d(TAG,
                        "ProfileInstaller: Error getting installation status: " + t.getMessage());
            }
        }, service);
    }
}

کدهای نتیجه زیر نکاتی را در مورد علت برخی مشکلات ارائه می‌دهند:

RESULT_CODE_COMPILED_WITH_PROFILE
این پروفایل نصب، کامپایل و هر زمان که برنامه اجرا می‌شود، استفاده می‌شود. این نتیجه‌ای است که می‌خواهید ببینید.
RESULT_CODE_ERROR_NO_PROFILE_EMBEDDED
هیچ پروفایلی در APK در حال اجرا یافت نمی‌شود. در صورت مشاهده این خطا، مطمئن شوید که از نسخه‌ای از ساخت استفاده می‌کنید که شامل پروفایل‌های پایه است و همچنین APK حاوی یک پروفایل است.
RESULT_CODE_NO_PROFILE
هنگام نصب برنامه از طریق اپ استور یا مدیریت بسته، هیچ پروفایلی برای این برنامه نصب نشده است. دلیل اصلی این کد خطا این است که نصب‌کننده پروفایل به دلیل غیرفعال بودن ProfileInstallerInitializer اجرا نشده است. توجه داشته باشید که وقتی این خطا گزارش می‌شود، هنوز یک پروفایل جاسازی‌شده در APK برنامه یافت می‌شود. وقتی پروفایل جاسازی‌شده‌ای یافت نمی‌شود، کد خطای RESULT_CODE_ERROR_NO_PROFILE_EMBEDDED بازگردانده می‌شود.
RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION
یک پروفایل در APK یا AAB یافت می‌شود و برای کامپایل در صف قرار می‌گیرد. وقتی یک پروفایل توسط ProfileInstaller نصب می‌شود، دفعه بعد که بهینه‌سازی DEX پس‌زمینه توسط سیستم اجرا می‌شود، برای کامپایل در صف قرار می‌گیرد. این پروفایل تا زمان اتمام کامپایل فعال نیست. تا زمانی که کامپایل کامل نشده است، سعی نکنید پروفایل‌های پایه خود را بنچمارک کنید. ممکن است لازم باشد پروفایل‌های پایه را مجبور به کامپایل کنید . این خطا هنگام نصب برنامه از Play Store یا package manager در دستگاه‌هایی که اندروید ۹ (API 28) و بالاتر دارند، رخ نمی‌دهد، زیرا کامپایل در حین نصب انجام می‌شود.
RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING
یک پروفایل نامتناسب نصب شده و برنامه با آن کامپایل شده است. این نتیجه نصب از طریق فروشگاه گوگل پلی یا مدیریت بسته است. توجه داشته باشید که این نتیجه با RESULT_CODE_COMPILED_WITH_PROFILE متفاوت است زیرا پروفایل نامتناسب فقط متدهایی را که هنوز بین پروفایل و برنامه مشترک هستند کامپایل می‌کند. این پروفایل عملاً کوچکتر از حد انتظار است و متدهای کمتری نسبت به آنچه در پروفایل پایه گنجانده شده بود، کامپایل خواهند شد.
RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE
ProfileVerifier نمی‌تواند فایل کش نتیجه تأیید را بنویسد. این می‌تواند به دلیل وجود مشکل در مجوزهای پوشه برنامه یا عدم وجود فضای دیسک خالی کافی در دستگاه رخ دهد.
RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION
ProfileVerifier is running on an unsupported API version of Android. ProfileVerifier فقط از اندروید ۹ (سطح API ۲۸) و بالاتر پشتیبانی می‌کند.
RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST
هنگام درخواست از PackageManager برای بسته برنامه، PackageManager.NameNotFoundException رخ می‌دهد. این اتفاق به ندرت رخ می‌دهد. برنامه را حذف نصب و همه چیز را دوباره نصب کنید.
RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ
یک فایل کش نتایج تأیید قبلی وجود دارد، اما قابل خواندن نیست. این اتفاق به ندرت رخ می‌دهد. برنامه را حذف نصب و همه چیز را دوباره نصب کنید.

استفاده از ProfileVerifier در محیط عملیاتی

در محیط عملیاتی، می‌توانید ProfileVerifier به همراه کتابخانه‌های گزارش‌دهی تحلیلی، مانند Google Analytics برای Firebase ، برای تولید رویدادهای تحلیلی که وضعیت پروفایل را نشان می‌دهند، استفاده کنید. به عنوان مثال، اگر نسخه جدیدی از برنامه منتشر شود که حاوی پروفایل‌های پایه نباشد، این به سرعت به شما هشدار می‌دهد.

کامپایل اجباری پروفایل‌های پایه

اگر وضعیت کامپایل Baseline Profiles شما RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION باشد، می‌توانید با استفاده از adb کامپایل فوری را اجباری کنید:

adb shell cmd package compile -r bg-dexopt PACKAGE_NAME

بررسی وضعیت کامپایل پروفایل پایه بدون ProfileVerifier

اگر ProfileVerifier استفاده نمی‌کنید، می‌توانید وضعیت کامپایل را با استفاده adb بررسی کنید، اگرچه به اندازه ProfileVerifier بینش عمیقی ارائه نمی‌دهد:

adb shell dumpsys package dexopt | grep -A 2 PACKAGE_NAME

استفاده از adb چیزی شبیه به کد زیر تولید می‌کند:

  [com.google.samples.apps.nowinandroid.demo]
    path: /data/app/~~dzJiGMKvp22vi2SsvfjkrQ==/com.google.samples.apps.nowinandroid.demo-7FR1sdJ8ZTy7eCLwAnn0Vg==/base.apk
      arm64: [status=speed-profile] [reason=bg-dexopt] [primary-abi]
        [location is /data/app/~~dzJiGMKvp22vi2SsvfjkrQ==/com.google.samples.apps.nowinandroid.demo-7FR1sdJ8ZTy7eCLwAnn0Vg==/oat/arm64/base.odex]

مقدار status وضعیت کامپایل پروفایل را نشان می‌دهد و یکی از مقادیر زیر است:

وضعیت کامپایل معنی
speed‑profile یک پروفایل کامپایل شده وجود دارد و در حال استفاده است.
verify هیچ پروفایل کامپایل‌شده‌ای وجود ندارد.

وضعیت verify به این معنی نیست که APK یا AAB حاوی پروفایل نیست، زیرا می‌تواند توسط وظیفه بهینه‌سازی DEX پس‌زمینه بعدی برای کامپایل در صف قرار گیرد.

مقدار دلیل نشان می‌دهد چه چیزی باعث کامپایل پروفایل می‌شود و یکی از مقادیر زیر است:

دلیل معنی
install‑dm یک نمایه پایه به صورت دستی یا توسط گوگل پلی هنگام نصب برنامه گردآوری شده است.
bg‑dexopt یک پروفایل در حالی که دستگاه شما در حالت آماده به کار بوده، گردآوری شده است. این ممکن است یک پروفایل پایه باشد، یا ممکن است پروفایلی باشد که در حین استفاده از برنامه جمع‌آوری شده است.
cmdline این کامپایل با استفاده از adb انجام شده است. این ممکن است یک پروفایل پایه باشد، یا ممکن است پروفایلی باشد که در طول استفاده از برنامه جمع‌آوری شده است.

تأیید برنامه‌ی Startup Profile در DEX و r8.json

قوانین Startup Profile در زمان ساخت توسط R8 برای بهینه‌سازی چیدمان کلاس‌ها در فایل‌های DEX شما استفاده می‌شوند. این بهینه‌سازی زمان ساخت با نحوه استفاده از Baseline Profiles ( baseline.prof ) متفاوت است، زیرا آن‌ها در APK یا AAB بسته‌بندی می‌شوند تا ART بتواند کامپایل روی دستگاه را انجام دهد. از آنجا که قوانین Startup Profile در طول فرآیند ساخت اعمال می‌شوند، فایل startup.prof جداگانه‌ای در APK یا AAB شما برای بررسی وجود ندارد. در عوض، تأثیر Startup Profiles در چیدمان فایل DEX قابل مشاهده است.

بررسی پیکربندی DEX با r8.json (توصیه شده برای AGP 8.8 یا بالاتر)

برای پروژه‌هایی که از افزونه‌ی اندروید گریدل (AGP) نسخه‌ی ۸.۸ یا بالاتر استفاده می‌کنند، می‌توانید با بررسی فایل r8.json تولید شده، تأیید کنید که آیا پروفایل راه‌اندازی (Startup Profile) اعمال شده است یا خیر. این فایل در AAB شما بسته‌بندی شده است.

  1. بایگانی AAB خود را باز کنید و فایل r8.json را پیدا کنید.
  2. فایل را برای آرایه dexFiles جستجو کنید، که فایل‌های DEX تولید شده را فهرست می‌کند.
  3. به دنبال یک شیء dexFiles باشید که شامل جفت کلید-مقدار "startup": true . این به صراحت نشان می‌دهد که قوانین Startup Profile برای بهینه‌سازی طرح‌بندی آن فایل DEX خاص اعمال شده‌اند.

    "dexFiles": [
     {
       "checksum": "...",
       "startup": true // This flag confirms profile application to this DEX file
     },
     // ... other DEX files
    ]
    

بررسی تنظیمات DEX برای همه نسخه‌های AGP

اگر از نسخه AGP پایین‌تر از ۸.۸ استفاده می‌کنید، بررسی فایل‌های DEX روش اصلی برای تأیید صحت اعمال پروفایل راه‌اندازی شماست. همچنین می‌توانید از این روش در صورتی که از AGP 8.8 یا بالاتر استفاده می‌کنید و می‌خواهید طرح DEX را به صورت دستی بررسی کنید، استفاده کنید. به عنوان مثال، اگر بهبود عملکرد مورد انتظار را مشاهده نمی‌کنید. برای بررسی چیدمان DEX، موارد زیر را انجام دهید:

  1. فایل AAB یا APK خود را با استفاده از Build > Analyze APK در اندروید استودیو باز کنید.
  2. به اولین فایل DEX بروید. برای مثال، classes.dex .
  3. محتویات این فایل DEX را بررسی کنید. شما باید بتوانید تأیید کنید که کلاس‌ها و متدهای حیاتی تعریف‌شده در فایل پروفایل راه‌اندازی ( startup-prof.txt ) در این فایل DEX اصلی وجود دارند. یک برنامه‌ی موفق به این معنی است که این اجزای حیاتی راه‌اندازی برای بارگذاری سریع‌تر در اولویت قرار گرفته‌اند.

مشکلات عملکرد

این بخش برخی از بهترین شیوه‌ها را برای تعریف صحیح و محک زدن پروفایل‌های پایه شما نشان می‌دهد تا بیشترین بهره را از آنها ببرید.

معیارهای استارتاپ را به درستی ارزیابی کنید

اگر معیارهای استارتاپ شما به خوبی تعریف شده باشند، پروفایل‌های پایه شما مؤثرتر خواهند بود. دو معیار کلیدی عبارتند از زمان نمایش اولیه (TTID) و زمان نمایش کامل (TTFD) .

TTID زمانی است که برنامه اولین فریم خود را ترسیم می‌کند. مهم است که این مقدار را تا حد امکان کوتاه نگه دارید زیرا نمایش چیزی به کاربر نشان می‌دهد که برنامه در حال اجرا است. شما حتی می‌توانید یک نشانگر پیشرفت نامشخص را نمایش دهید تا نشان دهید که برنامه پاسخگو است.

TTFD زمانی است که می‌توان با برنامه تعامل داشت. مهم است که این زمان را تا حد امکان کوتاه نگه دارید تا از سرخوردگی کاربر جلوگیری شود. اگر TTFD را به درستی علامت‌گذاری کنید، به سیستم می‌گویید که کدی که در مسیر TTFD اجرا می‌شود، بخشی از راه‌اندازی برنامه است. در نتیجه، سیستم احتمالاً این کد را در پروفایل قرار می‌دهد.

برای اینکه اپلیکیشن شما واکنش‌گرا به نظر برسد، TTID و TTFD را تا حد امکان کم نگه دارید.

سیستم قادر به تشخیص TTID، نمایش آن در Logcat و گزارش آن به عنوان بخشی از معیارهای راه‌اندازی است. با این حال، سیستم قادر به تعیین TTFD نیست و این وظیفه برنامه است که هنگام رسیدن به حالت تعاملی کاملاً ترسیم شده، گزارش دهد. می‌توانید این کار را با فراخوانی reportFullyDrawn() یا ReportDrawn در صورت استفاده از Jetpack Compose انجام دهید. اگر چندین کار پس‌زمینه دارید که باید قبل از اینکه برنامه کاملاً ترسیم شده تلقی شود، انجام شوند، می‌توانید از FullyDrawnReporter ، همانطور که در بهبود دقت زمان‌بندی راه‌اندازی توضیح داده شده است، استفاده کنید.

پروفایل‌های کتابخانه‌ای و پروفایل‌های سفارشی

هنگام سنجش تأثیر پروفایل‌ها، تفکیک مزایای پروفایل‌های برنامه شما از پروفایل‌های ارائه شده توسط کتابخانه‌ها، مانند کتابخانه‌های Jetpack، می‌تواند دشوار باشد. هنگام ساخت APK خود، افزونه Android Gradle علاوه بر پروفایل سفارشی شما، هر پروفایلی را که در وابستگی‌های کتابخانه وجود دارد، اضافه می‌کند. این برای بهینه‌سازی عملکرد کلی خوب است و برای نسخه‌های منتشر شده شما توصیه می‌شود. با این حال، اندازه‌گیری میزان افزایش عملکرد اضافی ناشی از پروفایل سفارشی شما را دشوار می‌کند.

یک راه سریع برای مشاهده دستی بهینه‌سازی‌های اضافی ارائه شده توسط پروفایل سفارشی شما، حذف آن و اجرای بنچمارک‌هایتان است. سپس آن را جایگزین کرده و دوباره بنچمارک‌هایتان را اجرا کنید. مقایسه این دو، بهینه‌سازی‌های ارائه شده توسط پروفایل‌های کتابخانه‌ای به تنهایی و پروفایل‌های کتابخانه‌ای به همراه پروفایل سفارشی شما را به شما نشان می‌دهد.

یک روش خودکار برای مقایسه پروفایل‌ها، ایجاد یک نسخه ساخت جدید است که فقط شامل پروفایل‌های کتابخانه و نه پروفایل سفارشی شما باشد. معیارهای این نسخه را با نسخه انتشار که شامل پروفایل‌های کتابخانه و پروفایل‌های سفارشی شما است، مقایسه کنید. مثال زیر نحوه تنظیم نسخه‌ای را نشان می‌دهد که فقط شامل پروفایل‌های کتابخانه است. یک نسخه جدید با نام releaseWithoutCustomProfile را به ماژول مصرف‌کننده پروفایل خود، که معمولاً ماژول برنامه شماست، اضافه کنید:

کاتلین

android {
  ...
  buildTypes {
    ...
    // Release build with only library profiles.
    create("releaseWithoutCustomProfile") {
      initWith(release)
    }
    ...
  }
  ...
}
...
dependencies {
  ...
  // Remove the baselineProfile dependency.
  // baselineProfile(project(":baselineprofile"))
}

baselineProfile {
  variants {
    create("release") {
      from(project(":baselineprofile"))
    }
  }
}

گرووی

android {
  ...
  buildTypes {
    ...
    // Release build with only library profiles.
    releaseWithoutCustomProfile {
      initWith(release)
    }
    ...
  }
  ...
}
...
dependencies {
  ...
  // Remove the baselineProfile dependency.
  // baselineProfile ':baselineprofile"'
}

baselineProfile {
  variants {
    release {
      from(project(":baselineprofile"))
    }
  }
}

مثال کد قبلی، وابستگی baselineProfile از همه گونه‌ها حذف می‌کند و به صورت انتخابی آن را فقط روی گونه release اعمال می‌کند. ممکن است عجیب به نظر برسد که وقتی وابستگی روی ماژول تولیدکننده پروفایل حذف می‌شود، پروفایل‌های کتابخانه همچنان اضافه می‌شوند. با این حال، این ماژول فقط مسئول تولید پروفایل سفارشی شما است. افزونه Android Gradle هنوز برای همه گونه‌ها در حال اجرا است و مسئول گنجاندن پروفایل‌های کتابخانه است.

همچنین باید نوع جدید را به ماژول تولیدکننده پروفایل اضافه کنید. در این مثال، ماژول تولیدکننده با نام :baselineprofile نامگذاری شده است.

کاتلین

android {
  ...
    buildTypes {
      ...
      // Release build with only library profiles.
      create("releaseWithoutCustomProfile") {}
      ...
    }
  ...
}

گرووی

android {
  ...
    buildTypes {
      ...
      // Release build with only library profiles.
      releaseWithoutCustomProfile {}
      ...
    }
  ...
}

وقتی بنچمارک را از اندروید استودیو اجرا می‌کنید، برای اندازه‌گیری عملکرد فقط با پروفایل‌های کتابخانه، نوع releaseWithoutCustomProfile را انتخاب کنید، یا برای اندازه‌گیری عملکرد با پروفایل‌های کتابخانه و سفارشی، نوع release را انتخاب کنید.

از راه‌اندازی برنامه‌ی متصل به ورودی/خروجی (I/O-bound) جلوگیری کنید

اگر برنامه شما در هنگام راه‌اندازی، فراخوانی‌های ورودی/خروجی یا شبکه زیادی انجام می‌دهد، می‌تواند هم بر زمان راه‌اندازی برنامه و هم بر دقت بنچمارک‌گیری شما تأثیر منفی بگذارد. این فراخوانی‌های سنگین می‌توانند زمان نامشخصی را به خود اختصاص دهند که با گذشت زمان و حتی بین تکرارهای یک بنچمارک یکسان، متفاوت است. فراخوانی‌های ورودی/خروجی عموماً بهتر از فراخوانی‌های شبکه هستند، زیرا دومی می‌تواند تحت تأثیر عوامل خارجی دستگاه و روی خود دستگاه قرار گیرد. از فراخوانی‌های شبکه در هنگام راه‌اندازی خودداری کنید. در جایی که استفاده از یکی از آنها اجتناب‌ناپذیر است، از ورودی/خروجی استفاده کنید.

ما توصیه می‌کنیم معماری برنامه خود را طوری تنظیم کنید که از راه‌اندازی برنامه بدون فراخوانی‌های شبکه یا ورودی/خروجی پشتیبانی کند، حتی اگر فقط برای استفاده در هنگام بنچمارک‌گیری راه‌اندازی باشد. این به تضمین کمترین تغییرپذیری ممکن بین تکرارهای مختلف بنچمارک‌های شما کمک می‌کند.

اگر برنامه شما از Hilt استفاده می‌کند، می‌توانید هنگام بنچمارک‌گیری در Microbenchmark و Hilt، پیاده‌سازی‌های I/O-bound جعلی ارائه دهید.

تمام مسیرهای مهم کاربر را پوشش دهید

پوشش دقیق تمام مراحل مهم سفر کاربر در تولید پروفایل پایه بسیار مهم است. هر مرحله‌ای از سفر کاربر که پوشش داده نشود، توسط پروفایل‌های پایه بهبود نخواهد یافت. مؤثرترین پروفایل‌های پایه شامل تمام مراحل رایج سفر کاربر در شروع کار و همچنین مراحل حساس به عملکرد درون برنامه‌ای کاربر مانند فهرست‌های پیمایش است.

تغییرات پروفایل زمان کامپایل تست A/B

از آنجایی که پروفایل‌های Startup و Baseline بهینه‌سازی زمان کامپایل هستند، تست A/B مستقیم روی APKهای مختلف با استفاده از فروشگاه Google Play معمولاً برای نسخه‌های نهایی پشتیبانی نمی‌شود. برای ارزیابی تأثیر در یک محیط شبیه به تولید، رویکردهای زیر را در نظر بگیرید:

  • انتشار خارج از چرخه : یک انتشار خارج از چرخه را برای درصد کمی از پایگاه کاربری خود آپلود کنید که فقط شامل تغییر پروفایل باشد. این به شما امکان می‌دهد معیارهای واقعی تفاوت عملکرد را جمع‌آوری کنید.

  • بنچمارک محلی : برنامه خود را به صورت محلی با و بدون اعمال پروفایل، بنچمارک کنید. با این حال، توجه داشته باشید که بنچمارک محلی بهترین سناریو را برای پروفایل‌ها به شما نشان می‌دهد، زیرا اثرات پروفایل‌های ابری از ART که در دستگاه‌های تولیدی وجود دارند را شامل نمی‌شود.