ใช้ไลบรารี Macrobenchmark เพื่อทดสอบกรณีการใช้งานที่ใหญ่ขึ้นของแอป
รวมถึงการเริ่มต้นแอปและการจัดการ UI ที่ซับซ้อน เช่น การเลื่อน
LazyColumnหรือการเรียกใช้ภาพเคลื่อนไหว หากต้องการทดสอบโค้ดในส่วนที่เล็กลง โปรดดูการทดสอบประสิทธิภาพระดับไมโคร หน้านี้แสดงวิธีตั้งค่าไลบรารี
Macrobenchmark
ไลบรารีจะแสดงผลการเปรียบเทียบไปยังคอนโซล Android Studio และไปยัง ไฟล์ JSON ที่มีรายละเอียดเพิ่มเติม นอกจากนี้ ยังมีไฟล์การติดตามที่คุณโหลดและ วิเคราะห์ใน Android Studio ได้ด้วย
ใช้ไลบรารี Macrobenchmark ในสภาพแวดล้อมการรวมอย่างต่อเนื่อง (CI) ตามที่อธิบายไว้ในการทดสอบประสิทธิภาพในการรวมอย่างต่อเนื่อง
คุณใช้ Macrobenchmark เพื่อสร้างโปรไฟล์พื้นฐานได้ ก่อนอื่นให้ตั้งค่า ไลบรารี Macrobenchmark จากนั้นคุณจะสร้างโปรไฟล์พื้นฐานได้
Macrobenchmark เป็นเครื่องมือที่แนะนำสำหรับการทดสอบ UI ที่สร้างด้วย Jetpack Compose ดูวิธีเขียนการทดสอบ UI Automator ที่โต้ตอบกับโหนด Compose ได้ที่การทำงานร่วมกัน
การตั้งค่าโปรเจ็กต์
เราขอแนะนำให้คุณใช้ Macrobenchmark กับ Android Studio เวอร์ชันล่าสุด
ตั้งค่าโมดูล 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 สร้างและเปรียบเทียบเฉพาะรสชาติของผลิตภัณฑ์ที่ระบุได้ ซึ่งจะเป็นประโยชน์หากคุณทราบว่ามีเพียงรสชาติของผลิตภัณฑ์เดียวเท่านั้นที่มีการกำหนดค่าที่เหมาะสมสำหรับการเปรียบเทียบ
กำหนด Product Flavor ในโมดูล :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
การทดสอบเปรียบเทียบมีให้ใช้งานผ่าน MacrobenchmarkRule กฎ JUnit4
API ในไลบรารี 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 เช่น เฟรมหลุด (Jank) ขณะเลื่อน
หากต้องการเปรียบเทียบประสิทธิภาพของแอปพลิเคชัน 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 Sample ของที่เก็บใน GitHub
แสดงความคิดเห็น
หากต้องการรายงานปัญหาหรือส่งคำขอฟีเจอร์สำหรับ Jetpack Macrobenchmark โปรดดูเครื่องมือติดตามปัญหาแบบสาธารณะ
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- บันทึกเมตริก Macrobenchmark
- สร้างโปรไฟล์พื้นฐาน {:#creating-profile-rules}
- วัดผลโดยอัตโนมัติด้วยไลบรารี Macrobenchmark {:#measuring-optimization}