نمایه‌سازی ساخت

پروژه‌های بزرگ‌تر، یا پروژه‌هایی که منطق ساخت سفارشی زیادی را پیاده‌سازی می‌کنند، ممکن است نیاز داشته باشند که برای پیدا کردن گلوگاه‌ها، نگاه عمیق‌تری به فرایند ساخت داشته باشید. می‌توانید این کار را با نمایه کردن مدت زمانی که Gradle برای اجرای هر فاز از چرخه حیات ساخت و هر تکلیف ساخت نیاز دارد انجام دهید. برای مثال، اگر نمایه ساخت شما نشان می‌دهد که Gradle زمان زیادی را صرف پیکربندی پروژه‌تان می‌کند، ممکن است پیشنهاد دهد که باید منطق ساخت سفارشی را از فاز پیکربندی خارج کنید. علاوه‌براین، اگر تکلیف mergeDevDebugResources مقدار زیادی از زمان ساخت را مصرف می‌کند، ممکن است نشان‌دهنده این باشد که باید یا تصاویر خود را به WebP تبدیل کنید یا فشرده‌سازی PNG را غیرفعال کنید.

اگر از Android Studio نسخه ۴.۰ یا بالاتر استفاده می‌کنید، بهترین راه برای بررسی مشکلات عملکرد ساخت، استفاده از Build Analyzer است.

علاوه‌براین، دو گزینه برای نمایه‌سازی ساخت شما خارج از Android Studio وجود دارد:

  1. ابزارgradle-profiler مستقل، ابزاری قدرتمند برای تجزیه‌وتحلیل عمیق ساخت شما.

  2. گزینه --profile Gradle، ابزاری مناسب که از خط فرمان Gradle دردسترس است.

استفاده از ابزار مستقل gradle-profiler

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

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

برخی‌از پیکربندی‌های راه‌اندازی پروژه برای محک‌زنی عبارت‌اند از:

  • نسخه‌های افزایه
  • نسخه‌های Gradle
  • تنظیمات JVM (اندازه پشته، اندازه permgen، زباله‌روبی، و غیره)
  • تعداد کارگران Gradle‏ (org.gradle.workers.max)
  • گزینه‌های مربوط به هر افزونه برای بهینه‌سازی بیشتر عملکرد

شروع کردن

  • با دنبال کردن این دستورالعمل‌ها، gradle-profiler را نصب کنید
  • اجرا: gradle-profiler --benchmark --project-dir <root-project> :app:assembleDebug

این کار یک ساخت کاملاً به‌روز را محک می‌زند زیرا --benchmark تکلیف را چندین بار بدون تغییر پروژه در بین آن‌ها اجرا می‌کند. سپس گزارش HTML در فهرست راهنمای profile-out/ تولید می‌کند که زمان‌های ساخت را به شما نشان می‌دهد.

سناریوهای دیگری وجود دارد که ممکن است برای محک‌زنی مفیدتر باشد:

  • تغییرات کد در بدنه روش در کلاسی که بیشتر کارتان را در آن انجام می‌دهید.
  • تغییرات میانای برنامه‌سازی کاربردی در واحدی که در سراسر پروژه‌تان استفاده می‌شود. اگرچه این تغییرات کمتر از تغییرات کد خودتان رخ می‌دهد، اما تأثیر بیشتری دارد و اندازه‌گیری آن مفید است.
  • ویرایش‌های چیدمان برای شبیه‌سازی تکرار در کار میانای کاربر.
  • ویرایش‌های رشته برای شبیه‌سازی کار با ترجمه.
  • ساخت‌های تمیز برای شبیه‌سازی تغییرات در خود ساخت (برای نمونه، به‌روزرسانی افزایه Android Gradle، به‌روزرسانی Gradle، یا ویرایش کد ساخت خودتان در buildSrc).

برای محک زدن این موارد استفاده، می‌توانید سناریویی ایجاد کنید که برای هدایت اجرای gradle-profiler استفاده می‌شود و تغییرات مناسب را در منابع شما اعمال می‌کند. بخش‌های زیر چند سناریو رایج را شرح می‌دهند.

نمایه‌سازی تنظیمات مختلف حافظه/ واحد پردازش مرکزی

برای محک زدن تنظیمات مختلف حافظه و واحد پردازش مرکزی، می‌توانید چند سناریو ایجاد کنید که از مقادیر مختلفی برای org.gradle.jvmargs استفاده می‌کنند. برای مثال، می‌توانید سناریوهایی ایجاد کنید:

# <root-project>/scenarios.txt
clean_build_2gb_4workers {
    tasks = [":app:assembleDebug"]
    gradle-args = ["--max-workers=4"]
    jvm-args = ["-Xmx2048m"]
    cleanup-tasks = ["clean"]
}
clean_build_parallelGC {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-XX:+UseParallelGC"]
    cleanup-tasks = ["clean"]
}

clean_build_G1GC_4gb {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-Xmx4096m", "-XX:+UseG1GC"]
    cleanup-tasks = ["clean"]
}

با اجرای gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt سه سناریو اجرا خواهد شد و می‌توانید مقایسه کنید که :app:assembleDebug برای هرکدام از این راه‌اندازی‌ها چقدر طول می‌کشد.

نمایه‌سازی نسخه‌های مختلف افزایه Gradle

برای اینکه متوجه شوید تغییر نسخه افزونه Gradle چه تأثیری بر زمان ساخت دارد، سناریویی برای محک‌زنی آن ایجاد کنید. This requires some preparation to make the plugin version injectable from the scenario. build.gradle ریشه را تغییر دهید:

# <root-project>/build.gradle
buildscript {
    def agpVersion = providers.systemProperty("agpVersion").forUseAtConfigurationTime().orNull ?: '4.1.0'

    ext.kotlin = providers.systemProperty('kotlinVersion').forUseAtConfigurationTime().orNull ?: '1.4.0'

    dependencies {
        classpath "com.android.tools.build:gradle:$agpVersion"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin"
    }
}

اکنون می‌توانید نسخه‌های افزایه Android Gradle و افزایه Kotlin Gradle را از فایل سناریوها مشخص کنید و از سناریو بخواهید روش جدیدی به فایل‌های منبع اضافه کند:

# <root-project>/scenarios.txt
non_abi_change_agp4.1.0_kotlin1.4.10 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.1.0"
      "kotlinVersion" = "1.4.10"
}

non_abi_change_agp4.2.0_kotlin1.4.20 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.2.0-alpha16"
      "kotlinVersion" = "1.4.20"
}

نمایه‌سازی ساخت افزایشی

اکثر نسخه‌های ساخت افزایشی هستند، که این امر باعث می‌شود این یکی از مهم‌ترین سناریوها برای نمایه‌سازی باشد. نمایه‌ساز Gradle پشتیبانی گسترده‌ای از نمایه‌سازی ساخت‌های افزایشی دارد. این ابزار می‌تواند با تغییر دادن بدنه روش، افزودن روش جدید، یا تغییر دادن چیدمان یا منبع رشته، تغییرات را به‌طور خودکار در فایل منبع اعمال کند. برای مثال، می‌توانید سناریوهای افزایشی مثل این ایجاد کنید:

# <root-project>/scenarios.txt
non_abi_change {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}

abi_change {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}

layout_change {
    tasks = [":app:assembleDebug"]
    apply-android-layout-change-to = "app/src/main/res/your_layout_file.xml"
}
string_resource_change {
    tasks = [":app:assembleDebug"]
    apply-android-resource-value-change-to = "app/src/main/res/values/strings.xml"
}

با اجرای gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt، گزارش HTML با داده‌های محک‌زنی تولید خواهد شد.

می‌توانید سناریوهای افزایشی را با تنظیمات دیگر، مانند اندازه پشته، تعداد کارگران، یا نسخه Gradle ترکیب کنید:

# <root-project>/scenarios.txt
non_abi_change_4g {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
}

non_abi_change_4g_8workers {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
    gradle-args = ["--max-workers=8"]
}

non_abi_change_3g_gradle67 {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx3072m"]
    version = ["6.7"]
}

نمایه‌سازی ساخت تمیز

برای محک‌زنی ساخت تمیز، می‌توانید سناریویی ایجاد کنید که برای اجرای gradle-profiler استفاده خواهد شد:

# <root-project>/scenarios.txt
clean_build {
    tasks = [":app:assembleDebug"]
    cleanup-tasks = ["clean"]
}

برای اجرای این سناریو، از فرمان زیر استفاده کنید:

gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt

استفاده از گزینه Gradle --profile

برای تولید و مشاهده نمایه ساخت از خط فرمان Gradle، مراحل زیر را انجام دهید:

  1. یک پایانه خط فرمان را در ریشه پروژه خود باز کنید.

  2. با وارد کردن فرمان زیر، ساخت تمیز را انجام دهید. هنگام نمایه کردن ساخت، باید بین هر ساختی که نمایه می‌کنید، یک ساخت تمیز انجام دهید زیرا Gradle وقتی ورودی‌های یک وظیفه (مانند کد منبع) تغییر نمی‌کنند، وظایف را نادیده می‌گیرد. بنابراین، ساخت دوم بدون تغییرات ورودی همیشه سریع‌تر اجرا می‌شود زیرا تکالیف دوباره اجرا نمی‌شوند. بنابراین، اجرای تکلیف clean بین ساخت‌هایتان تضمین می‌کند که کل فرایند ساخت را نمایه می‌کنید.

    // On Mac or Linux, run the Gradle wrapper using "./gradlew".
    gradlew clean
    
  3. ساخت اشکال‌زدایی یکی از نسخه‌های ویژه محصولتان را، مثلاً نسخه ویژه «dev»، با پرچم‌های زیر اجرا کنید:

    gradlew --profile --offline --rerun-tasks assemble<var>Flavor</var>Debug
    
    • ‫--profile: نمایه‌سازی را فعال می‌کند.

    • --offline: Gradle را از واکشی وابستگی‌های آنلاین غیرفعال می‌کند. این کار اطمینان می‌دهد که هرگونه تأخیر ناشی از تلاش Gradle برای به‌روزرسانی وابستگی‌های شما با داده‌های نمایه‌سازی شما تداخل نداشته باشد. باید قبلاً پروژه‌تان را یک‌بار ساخته باشید تا مطمئن شوید Gradle قبلاً وابستگی‌هایتان را بارگیری و ذخیره کرده است.

    • --rerun-tasks: Gradle را مجبور می‌کند همه تکالیف را دوباره اجرا کند و هرگونه بهینه‌سازی تکلیف را نادیده بگیرد.

  4. پس‌از تکمیل ساخت، از پنجره پروژه برای پیمایش به دایرکتوری project-root/build/reports/profile/ استفاده کنید (همان‌طور که در شکل ۱ نشان داده شده است).

    نمای پروژه «استودیو Android» که گزارش‌های نمایه HTML تولیدشده را
      در build/reports/profile نشان می‌دهد.
    شکل ۱. نمای «پروژه» مکان گزارش‌های نمایه را نشان می‌دهد.
  5. روی فایل profile-timestamp.html کلیک راست کنید و باز کردن در مرورگر > پیش‌فرض را انتخاب کنید. گزارش باید شبیه به گزارش نشان‌داده‌شده در شکل ۲ باشد. می‌توانید هر برگه را در گزارش بررسی کنید تا درباره ساخت خود اطلاعات کسب کنید، مانند برگه اجرای وظیفه که نشان می‌دهد Gradle چقدر زمان برای اجرای هر وظیفه ساخت صرف کرده است.

    گزارش نمایه ساخت در مرورگری که زمان ساخت پایه ۴۶٫۵۶۷ ثانیه‌ای را نشان می‌دهد.
    شکل ۲. گزارش نمایه ساخت در مرورگر باز می‌شود.
  6. اختیاری: قبل‌از ایجاد هرگونه تغییر در پروژه یا پیکربندی ساخت، فرمان مرحله ۳ را تکرار کنید، اما پرچم --rerun-tasks را حذف کنید. ازآنجایی‌که Gradle تلاش می‌کند با اجرا نکردن مجدد تکالیفی که ورودی‌هایشان تغییر نکرده است در زمان صرفه‌جویی کند، برگه اجرای تکلیف گزارش، تکالیف تغییرنکرده را به‌صورت UP-TO-DATE علامت‌گذاری می‌کند، همان‌طور که در شکل ۳ نشان داده شده است. این کار به شما کمک می‌کند تشخیص دهید کدام تکالیف درحال انجام کار هستند درحالی‌که نباید باشند. برای مثال، اگر تکلیف :app:processDevUniversalDebugManifest به‌عنوان UP-TO-DATE علامت‌گذاری نشده باشد، ممکن است نشان‌دهنده این باشد که پیکربندی ساخت شما مانیفست را با هر ساخت به‌طور پویا به‌روز می‌کند. بااین‌حال، برخی‌از تکالیف باید درطول هر ساخت اجرا شوند، مثل :app:checkDevDebugManifest.

    برگه «اجرای تکلیف» در گزارش نمایه ساخت که تکالیف برنامه را نشان می‌دهد
      که با زمان ساخت کل ۰٫۲۸۰ ثانیه به‌عنوان به‌روز علامت‌گذاری شده‌اند.
    شکل ۳.‏ برگه «اجرای تکلیف» نتایج اجرای تکلیف را نشان می‌دهد.

اکنون که گزارش نمایه ساخت را دارید، می‌توانید با بررسی اطلاعات موجود در هر برگه گزارش، به‌دنبال فرصت‌های بهینه‌سازی بگردید. برخی‌از تنظیمات ساخت به آزمایش نیاز دارند زیرا مزایای آن‌ها ممکن است بین پروژه‌ها و ایستگاه‌های کاری متفاوت باشد. برای مثال، پروژه‌هایی با پایگاه کد بزرگ ممکن است از کوچک کردن کد برای برداشتن کد استفاده‌نشده و کوچک کردن اندازه برنامه بهره ببرند. بااین‌حال، پروژه‌های کوچک‌تر ممکن است از غیرفعال کردن کامل کوچک کردن کد بهره بیشتری ببرند. علاوه‌براین، افزایش اندازه پشته Gradle (بااستفاده از org.gradle.jvmargs) ممکن است بر عملکرد در دستگاه‌های با حافظه کم تأثیر منفی بگذارد.

پس‌از ایجاد تغییر در پیکربندی ساخت، نتایج تغییراتتان را با تکرار مراحل قبلی و تولید نمایه ساخت جدید مشاهده کنید. برای مثال، شکل ۴ گزارشی را برای همان برنامه نمونه پس‌از اعمال برخی‌از بهینه‌سازی‌های پایه شرح‌داده‌شده در این سند نشان می‌دهد.

گزارش نمایه ساخت که زمان ساخت پس‌از بهینه‌سازی را ۲۹٫۶۶۸ ثانیه نشان می‌دهد،
      که نسبت‌به ۴۶٫۵۶۷ ثانیه در شکل ۲ کاهش یافته است.
شکل ۴. گزارش نمایه ساخت، زمان‌های ساخت سریع‌تری را پس‌از بهینه‌سازی سرعت ساخت نشان می‌دهد.