ใช้ไลบรารี Macrobenchmark เพื่อทดสอบกรณีการใช้งานขนาดใหญ่ของแอป ซึ่งรวมถึงการเริ่มต้นแอปและการจัดการ UI ที่ซับซ้อน เช่น การเลื่อน LazyColumn หรือการเรียกใช้ภาพเคลื่อนไหว หากต้องการทดสอบโค้ดในส่วนที่เล็กลง โปรดดูการเปรียบเทียบระดับไมโคร หน้านี้แสดงวิธีตั้งค่าไลบรารี Macrobenchmark
ไลบรารีจะแสดงผลลัพธ์การเปรียบเทียบไปยังคอนโซล Android Studio และไฟล์ JSON ที่มีรายละเอียดเพิ่มเติม นอกจากนี้ ยังมีไฟล์การติดตามที่คุณสามารถโหลดและวิเคราะห์ใน Android Studio ได้ด้วย
ใช้ไลบรารี Macrobenchmark ในสภาพแวดล้อมการรวมอย่างต่อเนื่อง (CI) ตามที่อธิบายไว้ในการเปรียบเทียบในการรวมอย่างต่อเนื่อง
คุณใช้ Macrobenchmark เพื่อสร้างโปรไฟล์พื้นฐานได้ ก่อนอื่นให้ตั้งค่าไลบรารี Macrobenchmark จากนั้นคุณจะสร้างโปรไฟล์พื้นฐานได้
Macrobenchmark เป็นเครื่องมือที่แนะนำสำหรับการทดสอบ UI ที่สร้างด้วย Jetpack Compose ดูวิธีเขียนการทดสอบ UI Automator ที่โต้ตอบกับโหนด Compose ได้ที่ความสามารถในการทำงานร่วมกัน
การตั้งค่าโปรเจ็กต์
เราขอแนะนำให้ใช้ Macrobenchmark กับ Android Studio เวอร์ชันล่าสุด
ตั้งค่าโมดูล Macrobenchmark
Macrobenchmark ต้องใช้โมดูล com.android.test ซึ่งแยกต่างหากจากโค้ดแอป และมีหน้าที่เรียกใช้การทดสอบที่วัดประสิทธิภาพแอป
ใน Android Studio มีเทมเพลตที่ช่วยให้การตั้งค่าโมดูล Macrobenchmark ง่ายขึ้น เทมเพลตโมดูลการเปรียบเทียบจะสร้างโมดูลในโปรเจ็กต์โดยอัตโนมัติเพื่อวัดแอปที่สร้างโดยโมดูลแอป ซึ่งรวมถึงการเปรียบเทียบการเริ่มต้นตัวอย่าง
หากต้องการใช้เทมเพลตโมดูลเพื่อสร้างโมดูลใหม่ ให้ทำดังนี้
คลิกขวาที่โปรเจ็กต์หรือโมดูลในแผงโปรเจ็กต์ใน Android Studio แล้วเลือกใหม่ > โมดูล
เลือกการเปรียบเทียบจากแผงเทมเพลต คุณสามารถปรับแต่งแอปเป้าหมาย ซึ่งหมายถึงแอปที่จะใช้เปรียบเทียบ รวมถึงชื่อแพ็กเกจและโมดูลสำหรับโมดูล Macrobenchmark ใหม่
คลิกเสร็จสิ้น
ตั้งค่าแอป
หากต้องการเปรียบเทียบแอป ซึ่งเรียกว่าเป้าหมายของ Macrobenchmark แอปต้องเป็น profileable ซึ่งช่วยให้อ่านข้อมูลการติดตามโดยละเอียดได้โดยไม่ส่งผลต่อประสิทธิภาพ วิซาร์ดโมดูลจะเพิ่มแท็ก <profileable> ลงในไฟล์ AndroidManifest.xml ของแอปโดยอัตโนมัติ
ตรวจสอบว่าแอปเป้าหมายมี ProfilerInstaller 1.3 ขึ้นไป ซึ่งไลบรารี Macrobenchmark ต้องใช้เพื่อเปิดใช้การบันทึกและรีเซ็ตโปรไฟล์ รวมถึงการล้างแคชตัวปรับเฉดสี
กำหนดค่าแอปที่เปรียบเทียบให้ใกล้เคียงกับเวอร์ชันที่เผยแพร่หรือเวอร์ชันที่ใช้งานจริงมากที่สุด ตั้งค่าเป็นแบบแก้ไขข้อบกพร่องไม่ได้ และควรเปิดการลดขนาดไว้ ซึ่งจะช่วยปรับปรุงประสิทธิภาพ โดยปกติแล้ว คุณจะทำได้โดยสร้างสำเนาของตัวแปรของรุ่น ซึ่งจะทำงานเหมือนกันแต่จะลงนามในเครื่องด้วยคีย์การแก้ไขข้อบกพร่อง
หรือจะใช้ initWith เพื่อสั่งให้ Gradle ดำเนินการแทนคุณก็ได้ ดังนี้
Kotlin
buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) } create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") } }
ดึงดูด
buildTypes { release { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "keep-rules.pro" ) // In real app, this would use its own release keystore signingConfig = signingConfigs.getByName("debug") baselineProfile.automaticGenerationDuringBuild = true } }
เพื่อช่วยให้มั่นใจว่าการเรียกใช้การเปรียบเทียบจะทั้งสร้างและทดสอบตัวแปรที่ถูกต้องของแอป ดังที่แสดงในรูปที่ 2 ให้ทำดังนี้
- ทำการซิงค์ Gradle
- เปิดแผงตัวแปรบิลด์
- เลือกตัวแปรเกณฑ์เปรียบเทียบของทั้งแอปและโมดูล Macrobenchmark
(ไม่บังคับ) ตั้งค่าแอปแบบหลายโมดูล
หากแอปมีโมดูล Gradle มากกว่า 1 โมดูล ให้ตรวจสอบว่าสคริปต์บิลด์ทราบว่าต้องคอมไพล์ตัวแปรบิลด์ใด เพิ่มพร็อพเพอร์ตี้ matchingFallbacks ลงในประเภทบิลด์ benchmark ของโมดูล :macrobenchmark และ :app โมดูล Gradle ที่เหลือจะมีการกำหนดค่าเหมือนเดิมได้
Kotlin
create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("release") }
ดึงดูด
benchmark { initWith buildTypes.release signingConfig signingConfigs.debug matchingFallbacks = ['release'] }
หากไม่มีการดำเนินการนี้ ประเภทบิลด์ benchmark ที่เพิ่มใหม่จะทำให้บิลด์ไม่สำเร็จและแสดงข้อความแสดงข้อผิดพลาดต่อไปนี้
> Could not resolve project :shared.
Required by:
project :app
> No matching variant of project :shared was found.
...
เมื่อเลือกตัวแปรบิลด์ในโปรเจ็กต์ ให้เลือก benchmark สำหรับโมดูล :app และ :macrobenchmark และเลือก release สำหรับโมดูลอื่นๆ ที่คุณมีในแอป ดังที่แสดงในรูปที่ 3
ดูข้อมูลเพิ่มเติมได้ที่แก้ไขข้อผิดพลาดในการบิลด์ที่เกี่ยวข้องกับการจับคู่ตัวแปร
(ไม่บังคับ) ตั้งค่าเวอร์ชันผลิตภัณฑ์
หากคุณตั้งค่าเวอร์ชันผลิตภัณฑ์ไว้หลายรายการในแอป ให้กำหนดค่าโมดูล :macrobenchmark เพื่อให้ทราบว่าควรสร้างและเปรียบเทียบเวอร์ชันผลิตภัณฑ์ใดของแอป
ตัวอย่างในหน้านี้ใช้เวอร์ชันผลิตภัณฑ์ 2 เวอร์ชันในโมดูล :app ซึ่งก็คือ demo และ production ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" // ... } create("production") { dimension = "environment" // ... } }
ดึงดูด
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' // ... } production { dimension 'environment' // ... } }
หากไม่มีการกำหนดค่านี้ คุณอาจได้รับข้อผิดพลาดเกี่ยวกับบิลด์ที่คล้ายกับข้อผิดพลาดที่เกิดจากโมดูล Gradle หลายโมดูล ดังนี้
Could not determine the dependencies of task ':macrobenchmark:connectedBenchmarkAndroidTest'.
> Could not determine the dependencies of null.
> Could not resolve all task dependencies for configuration ':macrobenchmark:benchmarkTestedApks'.
> Could not resolve project :app.
Required by:
project :macrobenchmark
> The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'benchmark', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.0'. However we cannot choose between the following variants of project :app:
- demoBenchmarkRuntimeElements
- productionBenchmarkRuntimeElements
All of them match the consumer attributes:
...
2 ส่วนต่อไปนี้จะอธิบายวิธีต่างๆ ในการกำหนดค่าการเปรียบเทียบกับเวอร์ชันผลิตภัณฑ์หลายรายการ
ใช้ missingDimensionStrategy
การระบุ missingDimensionStrategy ใน defaultConfig ของโมดูล :macrobenchmark จะบอกให้ระบบบิลด์กลับไปใช้มิติข้อมูลของเวอร์ชัน ระบุมิติข้อมูลที่จะใช้หากไม่พบในโมดูล
ในตัวอย่างต่อไปนี้ ระบบจะใช้รสชาติ production เป็นมิติข้อมูลเริ่มต้น
Kotlin
defaultConfig { missingDimensionStrategy("environment", "production") }
ดึงดูด
defaultConfig { missingDimensionStrategy "environment", "production" }
วิธีนี้ช่วยให้โมดูล :macrobenchmark สามารถสร้างและเปรียบเทียบเวอร์ชันผลิตภัณฑ์ที่ระบุเท่านั้น ซึ่งจะเป็นประโยชน์หากคุณทราบว่ามีเวอร์ชันผลิตภัณฑ์เพียงเวอร์ชันเดียวที่มีการกำหนดค่าที่เหมาะสมสำหรับการเปรียบเทียบ
กำหนดเวอร์ชันผลิตภัณฑ์ในโมดูล :macrobenchmark
หากต้องการสร้างและเปรียบเทียบเวอร์ชันผลิตภัณฑ์อื่นๆ ให้กำหนดเวอร์ชันเหล่านั้นในโมดูล :macrobenchmark ระบุในลักษณะเดียวกับในโมดูล :app แต่กำหนด productFlavors ให้กับ dimension เท่านั้น ไม่จำเป็นต้องมีการตั้งค่าอื่นๆ
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" } create("production") { dimension = "environment" } }
ดึงดูด
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' } production { dimension 'environment' } }
หลังจากกำหนดและซิงค์โปรเจ็กต์แล้ว ให้เลือกตัวแปรบิลด์ที่เกี่ยวข้องจากแผงตัวแปรบิลด์ ดังที่แสดงในรูปที่ 4
ดูข้อมูลเพิ่มเติมได้ที่แก้ไขข้อผิดพลาดในการบิลด์ที่เกี่ยวข้องกับการจับคู่ตัวแปร
สร้างคลาส Macrobenchmark
การทดสอบการเปรียบเทียบประสิทธิภาพมีให้บริการผ่าน API กฎ MacrobenchmarkRule JUnit4 ในไลบรารี Macrobenchmark ซึ่งมีเมธอด measureRepeated ที่ช่วยให้คุณระบุเงื่อนไขต่างๆ เกี่ยวกับวิธีเรียกใช้และเปรียบเทียบแอปเป้าหมายได้
คุณต้องระบุ packageName ของแอปเป้าหมาย สิ่งที่ต้องการวัด metrics และจำนวนครั้งที่การเปรียบเทียบต้องทำงาน iterations เป็นอย่างน้อย
Kotlin
@LargeTest @RunWith(AndroidJUnit4::class) class SampleStartupBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test fun startup() = benchmarkRule.measureRepeated( packageName = TARGET_PACKAGE, metrics = listOf(StartupTimingMetric()), iterations = DEFAULT_ITERATIONS, ) { // starts default launch activity uiAutomator { startApp(TARGET_PACKAGE) } } }
ดูตัวเลือกทั้งหมดในการปรับแต่งการเปรียบเทียบได้ที่ส่วนปรับแต่งการเปรียบเทียบ
เปรียบเทียบการโต้ตอบกับ UI ของ Compose
แม้ว่าตัวอย่างก่อนหน้านี้จะวัดการเริ่มต้นแอป แต่คุณมักจะต้องการวัดประสิทธิภาพ UI เช่น เฟรมที่หายไป (กระตุก) ขณะเลื่อน
หากต้องการเปรียบเทียบแอปพลิเคชัน Jetpack Compose เช่น เพื่อวัดFrameTimingMetricขณะเลื่อน LazyColumn คุณสามารถใช้ UI Automator เพื่อโต้ตอบกับโหนด Compose โดยตรง ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
@LargeTest
@RunWith(AndroidJUnit4::class)
class ComposeScrollBenchmark {
@get:Rule
val benchmarkRule = MacrobenchmarkRule()
@Test
fun scrollLazyColumn() = benchmarkRule.measureRepeated(
packageName = "com.example.compose.app",
metrics = listOf(FrameTimingMetric()),
iterations = 5,
startupMode = StartupMode.WARM,
setupBlock = { pressHome() }
) {
startActivityAndWait()
// Find the Compose node using the testTag defined in your app
val lazyColumn = device.findObject(By.res("my_lazy_column"))
// Simulate a scroll gesture to measure FrameTimingMetric
lazyColumn.setGestureMargin(device.displayWidth / 5)
lazyColumn.fling(Direction.DOWN)
}
}
เรียกใช้การเปรียบเทียบ
เรียกใช้การทดสอบจากภายใน Android Studio เพื่อวัดประสิทธิภาพของแอปในอุปกรณ์ คุณสามารถเรียกใช้การเปรียบเทียบได้ในลักษณะเดียวกับการเรียกใช้ @Test อื่นๆ โดยใช้การดำเนินการในแถบด้านข้างถัดจากคลาสหรือเมธอดทดสอบ ดังที่แสดงในรูปที่ 5
นอกจากนี้ คุณยังเรียกใช้การเปรียบเทียบทั้งหมดในโมดูล Gradle จากบรรทัดคำสั่งได้โดยเรียกใช้คำสั่ง connectedCheck ดังนี้
./gradlew :macrobenchmark:connectedCheckคุณเรียกใช้การทดสอบรายการเดียวได้โดยทำดังนี้
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startupดูข้อมูลเกี่ยวกับวิธีเรียกใช้และตรวจสอบการเปรียบเทียบในการรวมอย่างต่อเนื่องได้ที่การเปรียบเทียบในการรวมอย่างต่อเนื่อง
ผลการเปรียบเทียบ
หลังจากเรียกใช้การเปรียบเทียบเสร็จสมบูรณ์แล้ว เมตริกจะแสดงใน Android Studio โดยตรงและเป็นเอาต์พุตสำหรับการใช้งาน CI ในไฟล์ JSON การทำซ้ำที่วัดได้แต่ละครั้งจะบันทึกการติดตามของระบบแยกกัน คุณเปิดผลการติดตามเหล่านี้ได้โดยคลิกลิงก์ในแผงผลการทดสอบ ดังที่แสดงในรูปที่ 6
เมื่อโหลดการติดตามแล้ว Android Studio จะแจ้งให้คุณเลือกกระบวนการที่จะวิเคราะห์ ระบบจะป้อนข้อมูลการเลือกไว้ล่วงหน้าด้วยกระบวนการของแอปเป้าหมาย ดังที่แสดงในรูปที่ 7
หลังจากโหลดไฟล์การติดตามแล้ว Studio จะแสดงผลลัพธ์ในเครื่องมือสร้างโปรไฟล์ CPU ดังนี้
ระบบจะคัดลอกรายงาน JSON และการติดตามการทำโปรไฟล์จากอุปกรณ์ไปยังโฮสต์โดยอัตโนมัติด้วย โดยจะเขียนไว้ในเครื่องโฮสต์ในตำแหน่งต่อไปนี้
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
เข้าถึงไฟล์การติดตามด้วยตนเอง
หากต้องการใช้เครื่องมือ Perfetto เพื่อวิเคราะห์ไฟล์การติดตาม จะมีขั้นตอนเพิ่มเติมที่เกี่ยวข้อง Perfetto ช่วยให้คุณตรวจสอบกระบวนการทั้งหมดที่เกิดขึ้นในอุปกรณ์ระหว่างการติดตามได้ ขณะที่เครื่องมือสร้างโปรไฟล์ CPU ของ Android Studio จำกัดการตรวจสอบไว้ที่กระบวนการเดียว
หากคุณเรียกใช้การทดสอบจาก Android Studio หรือจากบรรทัดคำสั่ง Gradle ระบบจะคัดลอกไฟล์การติดตามจากอุปกรณ์ไปยังโฮสต์โดยอัตโนมัติ โดยจะเขียนไว้ในเครื่องโฮสต์ในตำแหน่งต่อไปนี้
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace
เมื่อมีไฟล์การติดตามในระบบโฮสต์แล้ว คุณสามารถเปิดไฟล์ใน Android Studio ได้โดยไปที่ File > Open ในเมนู ซึ่งจะแสดงมุมมองเครื่องมือวิเคราะห์ที่แสดงในส่วนก่อนหน้า
ข้อผิดพลาดในการกำหนดค่า
หากแอปได้รับการกำหนดค่าไม่ถูกต้อง (แก้ไขข้อบกพร่องได้หรือสร้างโปรไฟล์ไม่ได้) Macrobenchmark จะแสดงข้อผิดพลาดแทนการรายงานการวัดผลที่ไม่ถูกต้องหรือไม่สมบูรณ์ คุณสามารถระงับข้อผิดพลาดเหล่านี้ได้ด้วยอาร์กิวเมนต์ androidx.benchmark.suppressErrors
นอกจากนี้ Macrobenchmark ยังแสดงข้อผิดพลาดเมื่อพยายามวัดโปรแกรมจำลองหรือในอุปกรณ์ที่มีแบตเตอรี่ต่ำ ซึ่งอาจส่งผลต่อความพร้อมใช้งานของคอร์และความเร็วสัญญาณนาฬิกา
ปรับแต่งการเปรียบเทียบ
ฟังก์ชัน measureRepeated จะยอมรับพารามิเตอร์ต่างๆ ที่มีผลต่อเมตริกที่ไลบรารีรวบรวม วิธีเริ่มต้นและคอมไพล์แอป หรือจำนวนการทำซ้ำที่การเปรียบเทียบทำงาน
บันทึกเมตริก
เมตริกเป็นข้อมูลประเภทหลักที่ดึงมาจากการเปรียบเทียบ เมตริกที่พร้อมให้คุณใช้งานมีดังนี้
ดูข้อมูลเพิ่มเติมเกี่ยวกับเมตริกได้ที่บันทึกเมตริก Macrobenchmark
ปรับปรุงข้อมูลการติดตามด้วยเหตุการณ์ที่กำหนดเอง
การใช้เครื่องมือวัดในแอปด้วยเหตุการณ์การติดตามที่กำหนดเองอาจเป็นประโยชน์ ซึ่งจะเห็นได้จากรายงานการติดตามที่เหลือและช่วยชี้ให้เห็นปัญหาที่เฉพาะเจาะจงสำหรับแอปของคุณ ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้างเหตุการณ์การติดตามที่กำหนดเองได้ที่หัวข้อกำหนดเหตุการณ์ที่กำหนดเอง
CompilationMode
Macrobenchmark สามารถระบุ CompilationMode ซึ่งกำหนดปริมาณของแอปที่ต้องคอมไพล์ล่วงหน้าจากไบต์โค้ด DEX (รูปแบบไบต์โค้ดภายใน APK) เป็นรหัสเครื่อง (คล้ายกับ C++ ที่คอมไพล์ล่วงหน้า)
โดยค่าเริ่มต้น Macrobenchmark จะทำงานด้วย CompilationMode.DEFAULT ซึ่งจะติดตั้งโปรไฟล์พื้นฐาน (หากมี) ใน Android 7 (ระดับ API 24) ขึ้นไป
หากคุณใช้ Android 6 (ระดับ API 23) หรือเวอร์ชันก่อนหน้า โหมดการคอมไพล์จะคอมไพล์ APK อย่างสมบูรณ์ตามลักษณะการทำงานเริ่มต้นของระบบ
คุณสามารถติดตั้งโปรไฟล์พื้นฐานได้หากแอปเป้าหมายมีทั้งโปรไฟล์พื้นฐานและไลบรารี ProfileInstaller
ใน Android 7 ขึ้นไป คุณสามารถปรับแต่ง CompilationMode เพื่อให้ส่งผลต่อปริมาณการคอมไพล์ล่วงหน้าในอุปกรณ์เพื่อเลียนแบบการคอมไพล์ล่วงหน้า (AOT) หรือการแคช JIT ในระดับต่างๆ ดู CompilationMode.Full, CompilationMode.Partial, CompilationMode.None และ CompilationMode.Ignore
ฟีเจอร์นี้สร้างขึ้นจากคำสั่งการคอมไพล์ ART การเปรียบเทียบแต่ละรายการจะล้างข้อมูลโปรไฟล์ก่อนเริ่ม เพื่อช่วยให้มั่นใจว่าการเปรียบเทียบจะไม่รบกวนกัน
StartupMode
หากต้องการเริ่มกิจกรรม คุณสามารถส่งโหมดเริ่มต้นที่กำหนดไว้ล่วงหน้าได้ ซึ่งได้แก่ COLD, WARM หรือ HOT พารามิเตอร์นี้จะเปลี่ยนวิธีเปิดใช้งานกิจกรรมและสถานะกระบวนการเมื่อเริ่มการทดสอบ
ดูข้อมูลเพิ่มเติมเกี่ยวกับประเภทการเริ่มต้นได้ที่เวลาที่ใช้ในการเริ่มต้นแอป
ตัวอย่าง
โปรเจ็กต์ตัวอย่างมีอยู่ในตัวอย่าง Macrobenchmark ของที่เก็บใน GitHub
แสดงความคิดเห็น
หากต้องการรายงานปัญหาหรือส่งคำขอฟีเจอร์สำหรับ Jetpack Macrobenchmark โปรดดูเครื่องมือติดตามปัญหาแบบสาธารณะ
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- บันทึกเมตริก Macrobenchmark
- สร้างโปรไฟล์พื้นฐาน {:#creating-profile-rules}
- วัดผลโดยอัตโนมัติด้วยไลบรารี Macrobenchmark {:#measuring-optimization}