ดูวิธีใช้ไลบรารี 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เป็นAndroidBenchmarkRunnerKotlin
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 แยกต่างหากและตั้งค่าทรัพยากร Dependency ในโมดูลนั้นตามที่แสดงในรูปที่ 1
:app,
:microbenchmark, และ :benchmarkable ซึ่งช่วยให้ Microbenchmarks เปรียบเทียบประสิทธิภาพของโค้ดในโมดูล
:benchmarkable ได้หากต้องการเพิ่มโมดูล Gradle ใหม่ คุณสามารถใช้วิซาร์ดโมดูลใน Android Studio ได้ วิซาร์ดจะสร้างโมดูลที่กำหนดค่าไว้ล่วงหน้าสำหรับการเปรียบเทียบประสิทธิภาพ โดยจะเพิ่มไดเรกทอรีการเปรียบเทียบประสิทธิภาพและตั้งค่า debuggable เป็น false
คลิกขวาที่โปรเจ็กต์หรือโมดูลในแผงโปรเจ็กต์ ใน Android Studio แล้วคลิกใหม่ > โมดูล
เลือกการเปรียบเทียบประสิทธิภาพ ในแผงเทมเพลต
เลือกการเปรียบเทียบประสิทธิภาพแบบ 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 โดยใช้การดำเนินการใน Gutter ข้างคลาสหรือเมธอดทดสอบ ดังที่แสดงในรูปที่ 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 - ใช้อุปกรณ์จริง โดยระบบไม่รองรับอีมูเลเตอร์
- ล็อกนาฬิกาหากอุปกรณ์รูท
- ระดับแบตเตอรี่ในอุปกรณ์เพียงพออย่างน้อย 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}