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