كتابة معيار ماكرو

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

تُخرج المكتبة نتائج قياس الأداء إلى وحدة تحكّم "استوديو Android" وإلى ملف JSON يتضمّن تفاصيل أكثر. ويوفّر أيضًا ملفات تتبُّع يمكنك تحميلها وتحليلها في Android Studio.

استخدِم مكتبة Macrobenchmark في بيئة دمج مستمر (CI)، كما هو موضّح في مقالة قياس الأداء في عملية الدمج المستمر.

يمكنك استخدام Macrobenchmark لإنشاء "ملفات تعريف خط الأساس". عليك أولاً إعداد مكتبة Macrobenchmark، ثم يمكنك إنشاء ملف تعريف أساسي.

‫Macrobenchmark هي الأداة المقترَحة لاختبار واجهات المستخدم التي تم إنشاؤها باستخدام Jetpack Compose. للتعرّف على كيفية كتابة اختبارات UI Automator تتفاعل مع عقد Compose، يمكنك الاطّلاع على التشغيل التفاعلي.

إعداد المشروع

ننصحك باستخدام Macrobenchmark مع أحدث إصدار من "استوديو Android".

إعداد وحدة Macrobenchmark

تتطلّب اختبارات الأداء الشاملة وحدة com.android.test منفصلة عن رمز تطبيقك، وهي المسؤولة عن تنفيذ الاختبارات التي تقيس أداء تطبيقك.

يتوفّر نموذج في "استوديو Android" لتسهيل عملية إعداد وحدة Macrobenchmark. ينشئ نموذج وحدة قياس الأداء تلقائيًا وحدة في مشروعك لقياس أداء التطبيق الذي تم إنشاؤه بواسطة وحدة تطبيق، بما في ذلك نموذج لقياس أداء بدء التشغيل.

لاستخدام نموذج الوحدة لإنشاء وحدة جديدة، اتّبِع الخطوات التالية:

  1. انقر بزر الماوس الأيمن على مشروعك أو وحدتك في لوحة المشروع في "استوديو Android"، ثم اختَر جديد > وحدة.

  2. انقر على مقياس الأداء من لوحة النماذج. يمكنك تخصيص التطبيق المستهدَف، أي التطبيق الذي سيتم قياس أدائه، بالإضافة إلى اسم الحزمة واسم الوحدة للوحدة الجديدة Macrobenchmark.

  3. انقر على إنهاء.

نموذج "وحدة قياس الأداء"
الشكل 1. نموذج وحدة قياس الأداء

إعداد التطبيق

لتقييم أداء تطبيق، يُعرف باسم الهدف في Macrobenchmark، يجب أن يكون التطبيق profileable، ما يتيح قراءة معلومات التتبُّع التفصيلية بدون التأثير في الأداء. يضيف معالج الوحدة العلامة <profileable> تلقائيًا إلى ملف AndroidManifest.xml الخاص بالتطبيق.

تأكَّد من أنّ التطبيق المستهدَف يتضمّن الإصدار 1.3 أو إصدارًا أحدث من ProfilerInstaller، وهو الإصدار الذي تحتاج إليه مكتبة Macrobenchmark لتفعيل عملية تسجيل البيانات وإعادة الضبط ومحو ذاكرة التخزين المؤقت لبرامج التظليل.

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

Kotlin

buildTypes {
    getByName("release") {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"))
    }

    create("benchmark") {
        initWith(getByName("release"))
        signingConfig = signingConfigs.getByName("debug")
    }
}

أنيق

buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "keep-rules.pro"
        )
        // In real app, this would use its own release keystore
        signingConfig = signingConfigs.getByName("debug")
        baselineProfile.automaticGenerationDuringBuild = true
    }
}

للمساعدة في ضمان أنّ تشغيل مقياس الأداء ينشئ ويختبر صيغة التطبيق الصحيحة، كما هو موضّح في الشكل 2، اتّبِع الخطوات التالية:

  1. نفِّذ عملية مزامنة Gradle.
  2. افتح لوحة إصدارات الإنشاء.
  3. اختَر الإصدار المرجعي لكلّ من التطبيق ووحدة Macrobenchmark.
اختَر صيغة مقياس الأداء.
الشكل 2. اختَر السعر الأساسي.

(اختياري) إعداد تطبيق متعدد الوحدات

إذا كان تطبيقك يتضمّن أكثر من وحدة Gradle، تأكَّد من أنّ نصوص البرامج الإنشائية تعرف نوع الإصدار الذي يجب تجميعه. أضِف السمة matchingFallbacks إلى نوع الإصدار benchmark في الوحدتَين :macrobenchmark و:app. ويمكن أن تتضمّن بقية وحدات Gradle النمطية الإعدادات نفسها كما في السابق.

Kotlin

create("benchmark") {
    initWith(getByName("release"))
    signingConfig = signingConfigs.getByName("debug")

    matchingFallbacks += listOf("release")
 }

أنيق

benchmark {
    initWith buildTypes.release
    signingConfig signingConfigs.debug

    matchingFallbacks = ['release']
 }

بدون ذلك، يتسبّب نوع الإصدار benchmark الذي تمت إضافته حديثًا في تعذُّر إنشاء الإصدار ويعرض رسالة الخطأ التالية:

> Could not resolve project :shared.
     Required by:
         project :app
      > No matching variant of project :shared was found.
      ...

عند اختيار صيغ الإنشاء في مشروعك، اختَر benchmark لوحدتَي :app و:macrobenchmark، وrelease لأي وحدات أخرى لديك في تطبيقك، كما هو موضّح في الشكل 3:

متغيرات قياس الأداء لمشروع متعدد الوحدات مع تحديد نوعَي الإصدار والبنية لقياس الأداء
الشكل 3. متغيرات قياس الأداء لمشروع يتضمّن وحدات متعدّدة مع تحديد نوعَي الإصدار والبنية لقياس الأداء

لمزيد من المعلومات، راجِع مقالة حلّ أخطاء الإنشاء المتعلّقة بمطابقة الصيغ.

(اختياري) إعداد نُسخ المنتج

إذا كانت لديك صيغ منتجات متعددة تم ضبطها في تطبيقك، اضبط وحدة :macrobenchmark لكي تعرف صيغة المنتج التي سيتم إنشاء التطبيق بها وقياس أدائه.

تستخدم الأمثلة الواردة في هذه الصفحة نوعَي المنتج في الوحدة :app، demo وproduction، كما هو موضّح في المقتطف التالي:

Kotlin

flavorDimensions += "environment"
productFlavors {
    create("demo") {
        dimension = "environment"
        // ...
    }
    create("production") {
        dimension = "environment"
        // ...
    }
}

أنيق

flavorDimensions 'environment'
productFlavors {
    demo {
        dimension 'environment'
        // ...
    }

    production {
        dimension 'environment'
        // ...
    }
}

بدون عملية الضبط هذه، قد يظهر لك خطأ في الإصدار مشابه للخطأ الناتج عن وحدات Gradle المتعددة:

Could not determine the dependencies of task ':macrobenchmark:connectedBenchmarkAndroidTest'.
> Could not determine the dependencies of null.
   > Could not resolve all task dependencies for configuration ':macrobenchmark:benchmarkTestedApks'.
      > Could not resolve project :app.
        Required by:
            project :macrobenchmark
         > The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'benchmark', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.0'. However we cannot choose between the following variants of project :app:
             -   demoBenchmarkRuntimeElements
             -   productionBenchmarkRuntimeElements
           All of them match the consumer attributes:
           ...

يوضّح القسمان التاليان طرقًا لإعداد قياس الأداء باستخدام نُسخ متعددة من المنتج.

استخدام missingDimensionStrategy

يؤدي تحديد missingDimensionStrategy في defaultConfig ضمن وحدة :macrobenchmark إلى توجيه نظام الإصدار إلى استخدام سمة نوع المنتج الاحتياطية. حدِّد السمات التي تريد استخدامها إذا لم تعثر عليها في الوحدة. في المثال التالي، يتم استخدام السمة production كنظام أساسي للمكوّن:

Kotlin

defaultConfig {
    missingDimensionStrategy("environment", "production")
}

أنيق

defaultConfig {
    missingDimensionStrategy "environment", "production"
}

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

تحديد نكهات المنتج في وحدة :macrobenchmark

إذا أردت إنشاء صيغ أخرى من المنتج وقياس أدائها، عليك تحديدها في ملف :macrobenchmark. حدِّدها بشكل مشابه لما ورد في الوحدة :app، ولكن لا تُسنِد سوى productFlavors إلى dimension. لا يلزم إجراء أي إعدادات أخرى:

Kotlin

flavorDimensions += "environment"
productFlavors {
    create("demo") {
        dimension = "environment"
    }
    create("production") {
        dimension = "environment"
    }
}

أنيق

flavorDimensions 'environment'
productFlavors {
    demo {
        dimension 'environment'
    }

    production {
        dimension 'environment'
    }
}

بعد تحديد المشروع ومزامنته، اختَر صيغة الإصدار المناسبة من لوحة صيغ الإصدار، كما هو موضّح في الشكل 4:

خيارات المقارنة للمشروع الذي يتضمّن نكهات المنتج والتي تعرض productionBenchmark وrelease المحدّدين
الشكل 4. إصدارات تجريبية للمشروع مع نُسخ من المنتج تعرض الخيارَين "productionBenchmark" و "release" المحدّدين

لمزيد من المعلومات، راجِع مقالة حلّ أخطاء الإنشاء المتعلّقة بمطابقة الصيغ.

إنشاء فئة Macrobenchmark

يتم توفير اختبارات قياس الأداء من خلال واجهة برمجة التطبيقات MacrobenchmarkRule JUnit4 rule في مكتبة Macrobenchmark. يحتوي على طريقة measureRepeated تتيح لك تحديد شروط مختلفة حول كيفية تشغيل التطبيق المستهدَف وقياس أدائه.

يجب على الأقل تحديد packageName للتطبيق المستهدَف، وmetrics الذي تريد قياسه، وعدد مرات تنفيذ iterations.

Kotlin

@LargeTest
@RunWith(AndroidJUnit4::class)
class SampleStartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun startup() = benchmarkRule.measureRepeated(
        packageName = TARGET_PACKAGE,
        metrics = listOf(StartupTimingMetric()),
        iterations = DEFAULT_ITERATIONS,
    ) {
        // starts default launch activity
        uiAutomator { startApp(TARGET_PACKAGE) }
    }
}

للاطّلاع على جميع خيارات تخصيص مقياس الأداء، راجِع قسم تخصيص مقاييس الأداء.

قياس أداء تفاعلات Compose UI

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

لتقييم أداء تطبيق Jetpack Compose، مثلاً لقياس FrameTimingMetric أثناء التمرير في LazyColumn، يمكنك استخدام UI Automator للتفاعل مباشرةً مع عقد Compose، كما هو موضّح في المقتطف التالي.

@LargeTest
@RunWith(AndroidJUnit4::class)
class ComposeScrollBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    @Test
    fun scrollLazyColumn() = benchmarkRule.measureRepeated(
        packageName = "com.example.compose.app",
        metrics = listOf(FrameTimingMetric()),
        iterations = 5,
        startupMode = StartupMode.WARM,
        setupBlock = { pressHome() }
    ) {
        startActivityAndWait()

        // Find the Compose node using the testTag defined in your app
        val lazyColumn = device.findObject(By.res("my_lazy_column"))

        // Simulate a scroll gesture to measure FrameTimingMetric
        lazyColumn.setGestureMargin(device.displayWidth / 5)
        lazyColumn.fling(Direction.DOWN)
    }
}

تشغيل مقياس الأداء

.

يمكنك إجراء الاختبار من داخل &quot;استوديو Android&quot; لقياس أداء تطبيقك على جهازك. يمكنك تشغيل مقاييس الأداء بالطريقة نفسها التي تشغّل بها أي @Test أخرى باستخدام إجراء الهامش بجانب فئة الاختبار أو الطريقة، كما هو موضّح في الشكل 5.

نفِّذ Macrobenchmark باستخدام إجراء &quot;الرصيف&quot; بجانب فئة الاختبار.
الشكل 5. نفِّذ Macrobenchmark باستخدام إجراء الحاشية بجانب فئة الاختبار.

يمكنك أيضًا تشغيل جميع مقاييس الأداء في وحدة Gradle من سطر الأوامر من خلال تنفيذ الأمر connectedCheck:

./gradlew :macrobenchmark:connectedCheck

يمكنك إجراء اختبار واحد من خلال تنفيذ ما يلي:

./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup

راجِع قياس الأداء في التكامل المستمر للحصول على معلومات حول كيفية تنفيذ مقاييس الأداء ومراقبتها في التكامل المستمر.

نتائج قياس الأداء

بعد إجراء اختبار الأداء بنجاح، يتم عرض المقاييس مباشرةً في &quot;استوديو Android&quot; ويتم إخراجها لاستخدامها في الدمج المتواصل في ملف JSON. تسجّل كل تكرار تم قياسه عملية تتبُّع منفصلة للنظام. يمكنك فتح نتائج التتبُّع هذه من خلال النقر على الروابط في جزء نتائج الاختبار، كما هو موضّح في الشكل 6:

نتائج بدء تشغيل Macrobenchmark
الشكل 6. نتائج بدء تشغيل Macrobenchmark

عند تحميل التتبُّع، يطلب منك &quot;استوديو Android&quot; اختيار العملية التي تريد تحليلها. يتم ملء حقل الاختيار مسبقًا بعملية التطبيق المستهدَف، كما هو موضّح في الشكل 7:

اختيار عملية تتبُّع في &quot;استوديو Android&quot;
الشكل 7. اختيار عملية تتبُّع الأخطاء في "استوديو Android"

بعد تحميل ملف التتبُّع، يعرض "استوديو Android" النتائج في أداة تحليل استخدام وحدة المعالجة المركزية:

تتبُّع النظام
الشكل 8. تتبُّع الأداء في "استوديو YouTube"

يتم أيضًا نسخ تقارير JSON وأي عمليات تتبُّع لتحديد المشاكل تلقائيًا من الجهاز إلى المضيف. تتم كتابة هذه السجلّات على الجهاز المضيف في الموقع التالي:

project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/

الوصول إلى ملفات التتبُّع يدويًا

إذا أردت استخدام أداة Perfetto لتحليل ملف تتبُّع، عليك اتّباع خطوات إضافية. يتيح لك Perfetto فحص جميع العمليات التي تحدث على الجهاز أثناء عملية التتبُّع، بينما يقتصر فحص أداة تحليل استخدام وحدة المعالجة المركزية في Android Studio على عملية واحدة.

إذا استدعيت الاختبارات من &quot;استوديو Android&quot; أو من سطر أوامر Gradle، سيتم تلقائيًا نسخ ملفات التتبُّع من الجهاز إلى المضيف. يتم حفظ هذه السجلّات على الجهاز المضيف في الموقع التالي:

project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace

بعد الحصول على ملف التتبُّع في نظامك المضيف، يمكنك فتحه في &quot;استوديو Android&quot; من خلال النقر على ملف > فتح في القائمة. تعرض هذه الصورة طريقة عرض أداة إنشاء الملفات الشخصية الموضّحة في القسم السابق.

أخطاء في الإعدادات

في حال ضبط إعدادات التطبيق بشكل غير صحيح، أي إذا كان قابلاً للتصحيح أو غير قابل للتوصيف، تعرض مكتبة Macrobenchmark رسالة خطأ بدلاً من عرض قياس غير صحيح أو غير مكتمل. يمكنك إخفاء هذه الأخطاء باستخدام الوسيطة androidx.benchmark.suppressErrors.

تعرض مكتبة Macrobenchmark أيضًا أخطاء عند محاولة قياس أداء محاكي أو جهاز منخفض البطارية، ما قد يؤدي إلى التأثير في مدى توفّر النواة وسرعة الساعة.

تخصيص مقاييس الأداء

تقبل الدالة measureRepeated مَعلمات مختلفة تؤثّر في المقاييس التي تجمعها المكتبة أو طريقة بدء تطبيقك وتجميعه أو عدد التكرارات التي يتم تنفيذ مقياس الأداء بها.

تسجيل المقاييس

المقاييس هي النوع الرئيسي من المعلومات المستخرَجة من مقاييس الأداء. تتوفّر المقاييس التالية:

لمزيد من المعلومات حول المقاييس، راجِع تسجيل مقاييس Macrobenchmark.

تحسين بيانات التتبُّع باستخدام أحداث مخصّصة

قد يكون من المفيد تزويد تطبيقك بأحداث تتبُّع مخصّصة تظهر مع بقية تقرير التتبُّع ويمكن أن تساعد في تحديد المشاكل الخاصة بتطبيقك. لمزيد من المعلومات عن إنشاء أحداث تتبُّع مخصّصة، اطّلِع على تحديد الأحداث المخصّصة.

CompilationMode

يمكن أن تحدّد اختبارات Macrobenchmark CompilationMode، الذي يحدّد مقدار الرمز البرمجي الذي يجب أن يتم تجميعه مسبقًا من رمز بايت DEX (تنسيق رمز البايت داخل حزمة APK) إلى رمز الآلة (مشابه للغة C++ المجمّعة مسبقًا).

يتم تشغيل Macrobenchmark تلقائيًا باستخدام CompilationMode.DEFAULT، ما يؤدي إلى تثبيت "الملف الأساسي"، إذا كان متاحًا، على الإصدار 7 من نظام التشغيل Android (المستوى 24 لواجهة برمجة التطبيقات) والإصدارات الأحدث. إذا كنت تستخدم الإصدار 6 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات) أو إصدارًا أقدم، سيتم تجميع حزمة APK بالكامل كإجراء تلقائي للنظام.

يمكنك تثبيت "ملف مرجعي" إذا كان التطبيق المستهدَف يتضمّن كلاً من "ملف مرجعي" ومكتبة ProfileInstaller.

في نظام التشغيل Android 7 والإصدارات الأحدث، يمكنك تخصيص CompilationMode للتأثير في مقدار التجميع المسبق على الجهاز لمحاكاة مستويات مختلفة من التجميع المسبق (AOT) أو التخزين المؤقت أثناء التشغيل (JIT). يمكنك الاطّلاع على CompilationMode.Full وCompilationMode.Partial وCompilationMode.None وCompilationMode.Ignore.

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

StartupMode

لتنفيذ عملية بدء نشاط، يمكنك تمرير وضع بدء تشغيل محدّد مسبقًا: COLD أو WARM أو HOT. تغيّر هذه المَعلمة طريقة تشغيل النشاط وحالة العملية في بداية الاختبار.

لمزيد من المعلومات عن أنواع التشغيل، اطّلِع على وقت تشغيل التطبيق.

نماذج

يتوفّر مشروع نموذجي في نموذج Macrobenchmark الخاص بالمستودع على GitHub.

تقديم ملاحظات

للإبلاغ عن مشاكل أو إرسال طلبات ميزات في Jetpack Macrobenchmark، يُرجى الاطّلاع على أداة تتبُّع المشاكل العامة.