نمایه ساختتون

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

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

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

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

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

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

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

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

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

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

شروع کردن

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

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

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

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

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

پروفایل کردن تنظیمات مختلف حافظه/CPU

به منظور محک زدن تنظیمات مختلف حافظه و CPU، می توانید چندین سناریو ایجاد کنید که از مقادیر مختلف برای 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 چگونه بر زمان ساخت تأثیر می گذارد، سناریویی برای محک زدن آن ایجاد کنید. این نیاز به مقداری آماده سازی دارد تا نسخه پلاگین از روی سناریو قابل تزریق باشد. root 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 profiler پشتیبانی گسترده ای برای پروفایل سازی ساخت های افزایشی دارد. این می‌تواند با تغییر بدنه متد، افزودن متد جدید، یا تغییر طرح‌بندی یا منبع رشته، تغییرات را به صورت خودکار در فایل منبع اعمال کند. به عنوان مثال، شما می توانید سناریوهای افزایشی مانند این ایجاد کنید:

# <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 &lt;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 assembleFlavorDebug
    
    • --profile : پروفایل را فعال می کند.
    • --offline : Gradle را از واکشی وابستگی های آنلاین غیرفعال می کند. این اطمینان حاصل می کند که تاخیرهای ناشی از تلاش Gradle برای به روز رسانی وابستگی های شما با داده های پروفایل شما تداخل نداشته باشد. شما باید یک بار پروژه خود را ساخته باشید تا مطمئن شوید که Gradle قبلاً وابستگی های شما را دانلود و کش کرده است.
    • --rerun-tasks : Gradle را مجبور می کند تا همه کارها را مجدداً اجرا کند و هر گونه بهینه سازی کار را نادیده بگیرد.
  4. شکل 1. نمای پروژه که محل گزارش های پروفایل را نشان می دهد.

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

  5. روی فایل profile- timestamp .html راست کلیک کرده و Open in Browser > Default را انتخاب کنید. گزارش باید شبیه به آنچه در شکل 2 نشان داده شده است باشد. شما می توانید هر برگه را در گزارش بررسی کنید تا در مورد ساخت خود بیاموزید، مانند برگه Task Execution که نشان می دهد Gradle برای اجرای هر کار ساخت چه مدت زمان صرف کرده است.

    شکل 2. مشاهده گزارش در مرورگر.

  6. اختیاری: قبل از ایجاد هرگونه تغییر در پروژه یا پیکربندی ساخت، دستور مرحله 3 را تکرار کنید، اما پرچم --rerun-tasks حذف کنید. از آنجایی که Gradle سعی می کند با اجرای مجدد وظایفی که ورودی های آنها تغییر نکرده است در زمان صرفه جویی کند (همانطور که در شکل 3 نشان داده شده است در برگه Task Execution گزارش به عنوان UP-TO-DATE نشان داده شده است)، می توانید تشخیص دهید که کدام وظایف هستند. انجام کار در حالی که نباید باشد. برای مثال، اگر :app:processDevUniversalDebugManifest به‌عنوان UP-TO-DATE علامت‌گذاری نشده باشد، ممکن است نشان دهد که پیکربندی ساخت شما به‌صورت پویا مانیفست را با هر ساختنی به‌روزرسانی می‌کند. با این حال، برخی از کارها باید در طول هر ساخت اجرا شوند، مانند :app:checkDevDebugManifest .

    شکل 3. مشاهده نتایج اجرای کار.

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

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

شکل 4. مشاهده گزارش جدید پس از بهینه سازی سرعت ساخت.