كتابة مقياس أداء مصغّر

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

QuickStart

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

لإجراء قياس أداء لمرة واحدة، اتّبِع الخطوات التالية:

  1. أضِف المكتبة إلى ملف build.gradle أو build.gradle.kts في الوحدة:

    Kotlin

    dependencies {
        implementation("androidx.benchmark:benchmark-junit4:1.2.4")
    }

    أنيق

    dependencies {
        implementation 'androidx.benchmark:benchmark-junit4:1.2.4'
    }

    استخدِم تبعية implementation بدلاً من تبعية androidTestImplementation. إذا كنت تستخدم androidTestImplementation، لن يتم تشغيل مقاييس الأداء لأنّه لم يتم دمج ملف البيان الخاص بالمكتبة في ملف بيان التطبيق.

  2. عدِّل نوع الإصدار debug لكي لا يكون قابلاً لتصحيح الأخطاء:

    Kotlin

    android {
        ...
        buildTypes {
            debug {
                isDebuggable = false
            }
        }
    }

    أنيق

    android {
        ...
        buildTypes {
            debug {
                debuggable false
            }
        }
    }
  3. غيِّر testInstrumentationRunner إلى AndroidBenchmarkRunner:

    Kotlin

    android {
        ...
        defaultConfig {
            testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner"
        }
    }

    أنيق

    android {
        ...
        defaultConfig {
            testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner"
        }
    }
  4. أضِف مثيلاً من BenchmarkRule في ملف اختبار في الدليل androidTest لإضافة مقياس الأداء. لمزيد من المعلومات حول كتابة مقاييس الأداء، يُرجى الاطّلاع على إنشاء فئة Microbenchmark.

    يوضّح مقتطف الرمز التالي كيفية إضافة مقياس أداء إلى اختبار Instrumented:

    Kotlin

    @RunWith(AndroidJUnit4::class)
    class SampleBenchmark {
        @get:Rule
        val benchmarkRule = BenchmarkRule()
    
        @Test
        fun benchmarkSomeWork() {
            benchmarkRule.measureRepeated {
                doSomeWork()
            }
        }
    }

    Java

    @RunWith(AndroidJUnit4.class)
    class SampleBenchmark {
        @Rule
        public BenchmarkRule benchmarkRule = new BenchmarkRule();
    
        @Test
        public void benchmarkSomeWork() {
                BenchmarkRuleKt.measureRepeated(
                    (Function1<BenchmarkRule.Scope, Unit>) scope -> doSomeWork()
                );
           }
        }
    }

للتعرّف على كيفية كتابة مقياس أداء، انتقِل إلى إنشاء فئة Microbenchmark.

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

لإعداد مقاييس أداء منتظمة بدلاً من مقاييس أداء لمرة واحدة، قسِّم مقاييس الأداء إلى وحدة خاصة بها. يساعد ذلك في ضمان أنّ عملية الضبط، مثل ضبط debuggable على false، منفصلة عن الاختبارات العادية.

بما أنّ Microbenchmark تشغّل الرمز البرمجي مباشرةً، ضَع الرمز البرمجي الذي تريد قياس أدائه في وحدة Gradle منفصلة واضبط التبعية على هذه الوحدة كما هو موضّح في الشكل 1.

بنية التطبيق
الشكل 1. بنية التطبيق التي تتضمّن وحدات :app و:microbenchmark و:benchmarkable في Gradle، ما يتيح لوحدة Microbenchmarks قياس أداء الرمز البرمجي في الوحدة :benchmarkable.

لإضافة وحدة Gradle جديدة، يمكنك استخدام معالج الوحدات في "استوديو Android". ينشئ المعالج وحدة تم ضبطها مسبقًا لإجراء قياس الأداء، مع إضافة دليل قياس الأداء وضبط debuggable على false.

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

  2. انقر على مقياس الأداء في لوحة النماذج.

  3. اختَر اختبار الأداء المصغّر كنوع وحدة اختبار الأداء.

  4. اكتب "microbenchmark" لاسم الوحدة.

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

ضبط وحدة المكتبة الجديدة
الشكل 2. أضِف وحدة Gradle جديدة في الإصدار Bumblebee من &quot;استوديو Android&quot;.

بعد إنشاء الوحدة، غيِّر ملف build.gradle أو build.gradle.kts وأضِف androidTestImplementation إلى الوحدة التي تحتوي على الرمز البرمجي الذي سيتم قياس أدائه:

Kotlin

dependencies {
    // The module name might be different.
    androidTestImplementation(project(":benchmarkable"))
}

أنيق

dependencies {
    // The module name might be different.
    androidTestImplementation project(':benchmarkable')
}

إنشاء فئة Microbenchmark

مقاييس الأداء هي اختبارات قياس حالة التطبيق العادية. لإنشاء مقياس أداء، استخدِم فئة BenchmarkRule التي توفّرها المكتبة. لمقارنة الأنشطة، استخدِم ActivityScenario أو ActivityScenarioRule. لتقييم أداء رمز واجهة المستخدم، استخدِم @UiThreadTest.

يعرض الرمز التالي نموذجًا لمقياس أداء:

Kotlin

@RunWith(AndroidJUnit4::class)
class SampleBenchmark {
    @get:Rule
    val benchmarkRule = BenchmarkRule()

    @Test
    fun benchmarkSomeWork() {
        benchmarkRule.measureRepeated {
            doSomeWork()
        }
    }
}
    

Java

@RunWith(AndroidJUnit4.class)
class SampleBenchmark {
    @Rule
    public BenchmarkRule benchmarkRule = new BenchmarkRule();

    @Test
    public void benchmarkSomeWork() {
        final BenchmarkState state = benchmarkRule.getState();
        while (state.keepRunning()) {
            doSomeWork();
        }
    }
}
    

إيقاف التوقيت أثناء عملية الإعداد

يمكنك إيقاف التوقيت لأجزاء من الرمز لا تريد قياسها باستخدام الحظر runWithTimingDisabled{}. تمثّل هذه الأقسام عادةً بعض الرموز التي عليك تنفيذها في كل تكرار من اختبار الأداء.

Kotlin

// using random with the same seed, so that it generates the same data every run
private val random = Random(0)

// create the array once and just copy it in benchmarks
private val unsorted = IntArray(10_000) { random.nextInt() }

@Test
fun benchmark_quickSort() {
    // ...
    benchmarkRule.measureRepeated {
        // copy the array with timing disabled to measure only the algorithm itself
        listToSort = runWithTimingDisabled { unsorted.copyOf() }

        // sort the array in place and measure how long it takes
        SortingAlgorithms.quickSort(listToSort)
    }

    // assert only once not to add overhead to the benchmarks
    assertTrue(listToSort.isSorted)
}
    

Java

private final int[] unsorted = new int[10000];

public SampleBenchmark() {
    // Use random with the same seed, so that it generates the same data every
    // run.
    Random random = new Random(0);

    // Create the array once and copy it in benchmarks.
    Arrays.setAll(unsorted, (index) -> random.nextInt());
}

@Test
public void benchmark_quickSort() {
    final BenchmarkState state = benchmarkRule.getState();

    int[] listToSort = new int[0];

    while (state.keepRunning()) {
        
        // Copy the array with timing disabled to measure only the algorithm
        // itself.
        state.pauseTiming();
        listToSort = Arrays.copyOf(unsorted, 10000);
        state.resumeTiming();
        
        // Sort the array in place and measure how long it takes.
        SortingAlgorithms.quickSort(listToSort);
    }

    // Assert only once, not to add overhead to the benchmarks.
    assertTrue(SortingAlgorithmsKt.isSorted(listToSort));
}
    

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

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

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

تشغيل Microbenchmark
الشكل 3. تشغيل اختبار Microbenchmark باستخدام الإجراء الموجود في المساحة الجانبية بجانب فئة الاختبار

بدلاً من ذلك، يمكنك تشغيل connectedCheck من سطر الأوامر لتشغيل جميع الاختبارات من وحدة Gradle المحدّدة:

./gradlew benchmark:connectedCheck

أو اختبار واحد:

./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork

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

بعد تشغيل اختبار Microbenchmark بنجاح، يتم عرض المقاييس مباشرةً في Android Studio، ويتوفّر تقرير قياس أداء كامل بتنسيق JSON يتضمّن مقاييس إضافية ومعلومات عن الجهاز.

نتائج الاختبارات المصغّرة
الشكل 4. نتائج اختبارات الأداء الدقيقة

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

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

يتم تلقائيًا كتابة تقرير JSON على القرص على الجهاز فقط في مجلد الوسائط المشتركة الخارجية لحزمة APK التجريبية، والذي يقع عادةً في /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json.

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

ترصد المكتبة الشروط التالية لضمان إعداد مشروعك وبيئتك بشكل يتيح الحصول على أداء دقيق عند الإصدار:

  • تم ضبط خيار "قابل للتصحيح" على false.
  • يتم استخدام جهاز فعلي، لأنّ المحاكيات غير متوافقة.
  • يتم قفل الساعات إذا تم تحديد جذر الجهاز.
  • يجب أن يكون مستوى البطارية في الجهاز %25 على الأقل.

إذا تعذّر اجتياز أي من عمليات التحقّق السابقة، سيسجّل المقياس خطأ لتثبيط القياسات غير الدقيقة.

لكتم أنواع أخطاء معيّنة كتحذيرات ومنعها من إيقاف مقياس الأداء، مرِّر نوع الخطأ في قائمة قيم مفصولة بفاصلة إلى وسيطة قياس حالة التطبيق androidx.benchmark.suppressErrors.

يمكنك ضبط ذلك من نص Gradle البرمجي، كما هو موضّح في المثال التالي:

Kotlin

android {
    defaultConfig {
       
      testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY"
    }
}

أنيق

android {
    defaultConfig {
       
      testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY"
    }
}

يمكنك أيضًا إيقاف عرض الأخطاء من سطر الأوامر:

$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY

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