ดูวิธีใช้ไลบรารี Microbenchmark โดยเพิ่มการเปลี่ยนแปลงลงในโค้ดของแอปพลิเคชันได้ที่ส่วนคู่มือเริ่มต้นฉบับย่อ หากต้องการดูวิธีตั้งค่าแบบเต็มด้วยการเปลี่ยนแปลงที่ซับซ้อนมากขึ้นในฐานของโค้ด โปรดดูส่วนการตั้งค่าโปรเจ็กต์แบบเต็ม
การเริ่มต้นอย่างรวดเร็ว
ส่วนนี้แสดงวิธีลองใช้การเปรียบเทียบและทำการวัดผลแบบครั้งเดียวโดยไม่ต้องย้ายโค้ดไปยังโมดูล เพื่อให้ได้ผลลัพธ์ด้านประสิทธิภาพที่แม่นยำ ขั้นตอนเหล่านี้เกี่ยวข้องกับการปิดใช้การแก้ไขข้อบกพร่องในแอป ดังนั้นโปรดเก็บสำเนาการทำงานในเครื่องไว้โดยไม่ต้องคอมมิตการเปลี่ยนแปลงไปยังระบบควบคุมแหล่งที่มา
หากต้องการทำการเปรียบเทียบแบบครั้งเดียว ให้ทำดังนี้
เพิ่มไลบรารีลงในไฟล์
build.gradleหรือbuild.gradle.ktsของโมดูลKotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
ดึงดูด
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
ใช้ทรัพยากร Dependency
implementationแทนทรัพยากร DependencyandroidTestImplementationหากคุณใช้androidTestImplementationการเปรียบเทียบจะทำงานไม่สำเร็จเนื่องจากไฟล์ Manifest ของไลบรารีไม่ได้ผสานรวมเข้ากับไฟล์ Manifest ของแอปอัปเดตประเภทบิลด์
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เพื่อเพิ่มการเปรียบเทียบ ดูข้อมูลเพิ่มเติมเกี่ยวกับการเขียนการเปรียบเทียบได้ที่สร้างคลาส Microbenchmarkข้อมูลโค้ดต่อไปนี้แสดงวิธีเพิ่มการเปรียบเทียบลงในการทดสอบที่มีการใช้เครื่องมือวัด
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
:app, :microbenchmark และ :benchmarkable ซึ่งช่วยให้ Microbenchmark เปรียบเทียบโค้ดในโมดูล :benchmarkable ได้หากต้องการเพิ่มโมดูล Gradle ใหม่ คุณสามารถใช้วิซาร์ดโมดูลใน Android Studio ได้
วิซาร์ดจะสร้างโมดูลที่กำหนดค่าไว้ล่วงหน้าสำหรับการเปรียบเทียบ โดยเพิ่มไดเรกทอรี
การเปรียบเทียบและตั้งค่า debuggable เป็น false
คลิกขวาที่โปรเจ็กต์หรือโมดูลในแผงโปรเจ็กต์ใน 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') }
สร้างคลาส Microbenchmark
การเปรียบเทียบเป็นการทดสอบการวัดคุมมาตรฐาน หากต้องการสร้างการเปรียบเทียบ ให้ใช้คลาส BenchmarkRule ที่ไลบรารีมีให้ หากต้องการเปรียบเทียบกิจกรรม ให้ใช้ ActivityScenario หรือ ActivityScenarioRule หากต้องการเปรียบเทียบโค้ด UI ให้ใช้ @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 - มีการใช้อุปกรณ์จริง เนื่องจากระบบไม่รองรับโปรแกรมจำลอง
- ระบบจะล็อกนาฬิกาหากอุปกรณ์มีการรูท
- ระดับแบตเตอรี่ในอุปกรณ์เพียงพออย่างน้อย 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 ปิดอยู่
- เขียน Macrobenchmark
- สร้าง Microbenchmark โดยไม่ใช้ Gradle
- สร้างโปรไฟล์พื้นฐาน {:#creating-profile-rules}