إنشاء ملف شخصي

قد تتطلب المشاريع الأكبر حجمًا أو تلك التي تستخدم الكثير من منطق الإنشاء المخصّص إلقاء نظرة أعمق على عملية الإنشاء للعثور على المشاكل التي تؤدي إلى بطء الأداء. يمكنك إجراء ذلك من خلال تحليل الوقت الذي يستغرقه Gradle لتنفيذ كل مرحلة من مراحل دورة حياة عملية الإنشاء وكل مهمة من مهام الإنشاء. على سبيل المثال، إذا أظهر ملف الإصدار الشخصي أنّ Gradle يستغرق وقتًا طويلاً في ضبط مشروعك، قد يشير ذلك إلى أنّك بحاجة إلى نقل منطق الإصدار المخصّص خارج مرحلة الضبط. بالإضافة إلى ذلك، إذا كانت مهمة mergeDevDebugResources تستهلك قدرًا كبيرًا من وقت التصميم، قد يشير ذلك إلى أنّك بحاجة إلى تحويل صورك إلى WebP أو إيقاف تصغير حجم ملفات PNG.

إذا كنت تستخدم الإصدار 4.0 من "استوديو Android" أو إصدارًا أحدث، فإنّ أفضل طريقة للتحقيق في مشاكل أداء عملية الإنشاء هي استخدام أداة تحليل الإصدار.

بالإضافة إلى ذلك، يتوفّر خياران لتحديد الملف الشخصي لإصدارك خارج "استوديو Android":

  1. أداة gradle-profiler المستقلة، وهي أداة فعّالة لإجراء تحليل عميق لإصدارك

  2. خيار --profile في Gradle، وهو أداة ملائمة متاحة من سطر أوامر Gradle

استخدام أداة gradle-profiler المستقلة

للعثور على إعدادات المشروع التي توفّر لك أفضل سرعة إنشاء، عليك استخدام أداة تحليل أداء Gradle، وهي أداة لجمع معلومات تحليل الأداء وقياس الأداء لعمليات إنشاء Gradle. يتيح لك Gradle profiler إنشاء سيناريوهات إنشاء وتشغيلها عدة مرات، ما يمنع التباين الكبير بين النتائج ويضمن إمكانية تكرار النتائج.

يجب استخدام وضع قياس الأداء لجمع معلومات حول عمليات الإنشاء النظيفة والتزايدية، بينما يمكن استخدام وضع جمع البيانات لجمع معلومات أكثر تفصيلاً حول عمليات التشغيل، بما في ذلك لقطات وحدة المعالجة المركزية.

تشمل بعض إعدادات ضبط المشروع لقياس الأداء ما يلي:

  • إصدارات المكوّنات الإضافية
  • إصدارات Gradle
  • إعدادات JVM (حجم الذاكرة المؤقتة، وحجم permgen، وجمع البيانات المُهمَلة، وما إلى ذلك)
  • عدد عمال Gradle‏ (org.gradle.workers.max)
  • خيارات لكل مكوّن إضافي لتحسين الأداء بشكل أكبر

الخطوات الأولى

  • ثبِّت gradle-profiler باتّباع هذه التعليمات
  • الجري: gradle-profiler --benchmark --project-dir <root-project> :app:assembleDebug

سيؤدي ذلك إلى قياس أداء إصدار محدَّث بالكامل لأنّ --benchmark ينفّذ المهمة عدة مرات بدون تغيير المشروع بينها. بعد ذلك، سيتم إنشاء تقرير HTML ضمن دليل profile-out/ يعرض لك أوقات الإنشاء.

هناك سيناريوهات أخرى قد تكون أكثر فائدة لقياس الأداء:

  • تغييرات في الرمز البرمجي في نص طريقة في فئة تؤدي فيها معظم عملك.
  • تغييرات في واجهة برمجة التطبيقات في وحدة يتم استخدامها في جميع أنحاء مشروعك وعلى الرغم من أنّ هذه التغييرات أقل تكرارًا من التغييرات التي تطرأ على الرمز البرمجي الخاص بك، إلا أنّ تأثيرها أكبر ومن المفيد قياسها.
  • تعديلات على التنسيق لمحاكاة التكرار في عمل واجهة المستخدم.
  • تعديلات على السلسلة لمحاكاة التعامل مع أعمال الترجمة
  • عمليات الإنشاء النظيفة لمحاكاة التغييرات على عملية الإنشاء نفسها (مثل تحديث المكوّن الإضافي لنظام Gradle المتوافق مع Android أو تحديث Gradle أو تعديلات على رمز الإنشاء الخاص بك ضمن buildSrc)

In order to benchmark these use cases, you can create a scenario that will be used to drive the gradle-profiler execution and which applies appropriate changes to your sources. توضّح الأقسام التالية بعض السيناريوهات الشائعة.

تحليل إعدادات الذاكرة/وحدة المعالجة المركزية المختلفة

لتقييم إعدادات الذاكرة ووحدة المعالجة المركزية المختلفة، يمكنك إنشاء سيناريوهات متعددة تستخدم قيمًا مختلفة لـ 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 في أوقات الإنشاء، أنشئ سيناريو لقياس الأداء. يتطلّب ذلك بعض الاستعدادات لجعل إصدار المكوّن الإضافي قابلاً للحقن من السيناريو. غيِّر ملف 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"
    }
}

يمكنك الآن تحديد إصدارات المكوّن الإضافي لنظام Gradle المتوافق مع Android والمكوّن الإضافي لنظام Gradle المتوافق مع Kotlin من ملف السيناريوهات، وإضافة طريقة جديدة إلى ملفات المصدر من خلال السيناريو:

# <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 <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/ (كما هو موضّح في الشكل 1).

    الشكل 1: عرض المشروع الذي يشير إلى موقع تقارير الملف الشخصي

  5. انقر بزر الماوس الأيمن على ملف profile-timestamp.html واختَر فتح في المتصفح > تلقائي. يجب أن يبدو التقرير مشابهًا للتقرير الموضح في الشكل 2. يمكنك فحص كل علامة تبويب في التقرير للتعرّف على عملية الإنشاء، مثل علامة التبويب تنفيذ المهام التي تعرض الوقت الذي استغرقه Gradle لتنفيذ كل مهمة إنشاء.

    الشكل 2: عرض تقرير في متصفّح

  6. اختياري: قبل إجراء أي تغييرات على مشروعك أو إعدادات التصميم، كرِّر الأمر في الخطوة 3، ولكن احذف العلامة --rerun-tasks. بما أنّ Gradle يحاول توفير الوقت من خلال عدم إعادة تنفيذ المهام التي لم تتغيّر مدخلاتها (يُشار إليها باسم UP-TO-DATE في علامة التبويب تنفيذ المهام في التقرير، كما هو موضّح في الشكل 3)، يمكنك تحديد المهام التي يتم تنفيذها في الوقت الذي لا ينبغي فيه تنفيذها. على سبيل المثال، إذا لم يتم وضع علامة UP-TO-DATE على :app:processDevUniversalDebugManifest، قد يشير ذلك إلى أنّ إعدادات التصميم تعدّل البيان ديناميكيًا مع كل عملية تصميم. ومع ذلك، يجب تنفيذ بعض المهام أثناء كل عملية إنشاء، مثل :app:checkDevDebugManifest.

    الشكل 3: عرض نتائج تنفيذ المهام

بعد الحصول على تقرير ملف تعريف الإصدار، يمكنك البدء في البحث عن فرص التحسين من خلال فحص المعلومات في كل علامة تبويب في التقرير. تتطلّب بعض إعدادات الإصدارات التجربة لأنّ المزايا قد تختلف بين المشاريع ومحطات العمل. على سبيل المثال، قد تستفيد المشاريع التي تحتوي على قاعدة الرموز البرمجية كبيرة من تخفيض حجم الرموز لإزالة الرموز غير المستخدَمة وتقليص حجم التطبيق. ومع ذلك، قد تستفيد المشاريع الأصغر حجمًا بشكل أكبر من إيقاف تخفيض حجم الرموز تمامًا. بالإضافة إلى ذلك، قد تؤثر زيادة حجم الذاكرة المؤقتة في Gradle (باستخدام org.gradle.jvmargs) سلبًا في الأداء على الأجهزة ذات الذاكرة المنخفضة.

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

الشكل 4. عرض تقرير جديد بعد تحسين سرعة الإصدار