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

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

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

استخدِم مكتبة 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. Benchmark variants for multi-module project with release and benchmark build types selected.

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

(اختياري) إعداد صيغ المنتج

إذا كانت لديك صيغ منتجات متعددة في تطبيقك، اضبط وحدة :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 في مكتبة 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

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

لإجراء قياس أداء لتطبيق 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)
    }
}

بدء قياس الأداء

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

شغِّل Macrobenchmark باستخدام إجراء الهامش بجانب فئة الاختبار.
الشكل 5. شغِّل Macrobenchmark باستخدام إجراء الهامش بجانب فئة الاختبار.

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

./gradlew :macrobenchmark:connectedCheck

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

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

يُرجى الاطّلاع على قياس الأداء في التكامل المستمر للحصول على معلومات حول كيفية إجراء عمليات قياس الأداء ومراقبتها في التكامل المستمر.

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

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

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

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

اختيار عملية تتبُّع في Studio
الشكل 7. اختيار عملية تتبُّع في "استوديو Android"

بعد تحميل ملف التتبُّع، يعرض Studio النتائج في أداة محلّل وحدة المعالجة المركزية (CPU):

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

يتم أيضًا نسخ تقارير JSON وأي آثار لإنشاء الملفات الشخصية تلقائيًا من الجهاز إلى المضيف. تتم كتابة هذه الملفات على الجهاز المضيف في الموقع التالي:

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

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

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

إذا استدعيت الاختبارات من "استوديو Android" أو من سطر أوامر 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++‎ المجمّعة مسبقًا).

يتم تشغيل اختبارات Macrobenchmarks تلقائيًا باستخدام CompilationMode.DEFAULT، ما يؤدي إلى تثبيت ملف أداء أساسي، في حال توفّره، على الإصدار 7 من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 24) والإصدارات الأحدث. إذا كنت تستخدم الإصدار Android 6 (مستوى واجهة برمجة التطبيقات 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، يُرجى الاطّلاع على أداة تتبُّع المشاكل العامة.