כדי ללמוד איך להשתמש בספריית Microbenchmark על ידי הוספת שינויים לקוד האפליקציה, אפשר לעיין בקטע מדריך למתחילים. כדי ללמוד איך להשלים הגדרה מלאה עם שינויים מורכבים יותר בבסיס הקוד, אפשר לעיין בקטע הגדרה מלאה של פרויקט.
מדריך למתחילים
בקטע הזה מוסבר איך לנסות את ההשוואה לשוק ולהריץ מדידות חד-פעמיות בלי להעביר קוד למודולים. כדי לקבל תוצאות מדויקות של הביצועים, צריך להשבית את ניפוי הבאגים באפליקציה. לכן, כדאי לשמור את השינויים בעותק מקומי ולא לבצע commit של השינויים במערכת לניהול קוד מקור.
כדי לבצע השוואה חד-פעמית לשוק:
מוסיפים את הספרייה לקובץ
build.gradle
אוbuild.gradle.kts
של המודול:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
מגניב
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
במקום להשתמש בתלות
androidTestImplementation
, צריך להשתמש בתלותimplementation
. אם משתמשים ב-androidTestImplementation
, ההשוואות לא יפעלו כי המניפסט של הספרייה לא מוזג עם המניפסט של האפליקציה.מעדכנים את סוג ה-build
debug
כך שלא ניתן יהיה לבצע בו ניפוי באגים:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
מגניב
android { ... buildTypes { debug { debuggable false } } }
משנים את הערך של
testInstrumentationRunner
ל-AndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
מגניב
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
כדי להוסיף את המדד, מוסיפים מופע של
BenchmarkRule
בקובץ בדיקה בספרייהandroidTest
. מידע נוסף על כתיבת מדדים להשוואה זמין במאמר יצירת מחלקה של מדד להשוואה.בקטע הקוד הבא מוצג איך מוסיפים מדד השוואה לבדיקה עם מכשור:
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() ); } } }
כדי ללמוד איך לכתוב מדד השוואה, אפשר לדלג אל יצירת מחלקה של מיקרו-מדד השוואה.
הגדרה מלאה של הפרויקט
כדי להגדיר השוואה קבועה לביצועים במקום השוואה חד-פעמית, צריך לבודד את הבנצ'מרקים למודול משלהם. כך תוכלו לוודא שההגדרה שלהם, כמו הגדרת debuggable
ל-false
, נפרדת מבדיקות רגילות.
הספרייה Microbenchmark מריצה את הקוד שלכם ישירות, ולכן צריך להציב את הקוד שרוצים לבצע לו בנצ'מרקינג במודול Gradle נפרד ולהגדיר תלות במודול הזה, כמו שמוצג באיור 1.

:app
, :microbenchmark
ו-:benchmarkable
Gradle, שמאפשרים ל-Microbenchmarks לבצע בנצ'מרקינג של קוד במודול :benchmarkable
.כדי להוסיף מודול Gradle חדש, אפשר להשתמש באשף המודולים ב-Android Studio. אשף יוצר מודול שמוגדר מראש להשוואה לשוק, עם ספריית השוואה לשוק שנוספה ועם debuggable
שמוגדר ל-false
.
לוחצים לחיצה ימנית על הפרויקט או המודול בחלונית Project ב-Android Studio ולוחצים על New > Module (חדש > מודול).
בוחרים באפשרות השוואה לשוק בחלונית תבניות.
בוחרים באפשרות Microbenchmark (מיקרו-מדד השוואה) כסוג מודול מדד ההשוואה.
מקלידים microbenchmark בשם המודול.
לוחצים על סיום.

אחרי שיוצרים את המודול, משנים את הקובץ 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') }
יצירת מחלקה של מיקרו-בנצ'מרק
בדיקות השוואה הן בדיקות אינסטרומנטציה רגילות. כדי ליצור מדד השוואה, משתמשים במחלקה 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 Studio, מריצים את הבדיקה כמו כל @Test
באמצעות פעולת השוליים שליד מחלקת הבדיקה או השיטה, כמו שמוצג באיור 3.

לחלופין, משורת הפקודה, מריצים את הפקודה connectedCheck
כדי להריץ את כל הבדיקות ממודול Gradle שצוין:
./gradlew benchmark:connectedCheck
או בדיקה אחת:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
תוצאות ההשוואה לשוק
אחרי הרצה מוצלחת של Microbenchmark, המדדים מוצגים ישירות ב-Android Studio, ודוח השוואה מלא עם מדדים נוספים ופרטי המכשיר זמין בפורמט JSON.

דוחות 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
.
שגיאות בהגדרות
הספרייה מזהה את התנאים הבאים כדי לוודא שהפרויקט והסביבה מוגדרים לביצועים מדויקים של הגרסה:
- האפשרות Debuggable מוגדרת ל-
false
. - נעשה שימוש במכשיר פיזי – אין תמיכה באמולטורים.
- השעונים נעולים אם המכשיר עבר תהליך רוט (Root).
- רמת הטעינה של הסוללה במכשיר מספיקה, לפחות 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_
לשמות הבדיקות.
מומלץ עבורך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- כתיבת מאקרו-בנצ'מרק
- יצירת מיקרו-בנצ'מרקים ללא Gradle
- יצירת פרופילים של Baseline {:#creating-profile-rules}