เมตริกเป็นข้อมูลประเภทหลักที่ดึงมาจากเกณฑ์มาตรฐาน โดยจะส่งไปยังmeasureRepeatedฟังก์ชันเป็นListซึ่งช่วยให้คุณระบุเมตริกที่วัดได้หลายรายการพร้อมกัน ต้องระบุเมตริกอย่างน้อย 1 ประเภทเพื่อให้เกณฑ์มาตรฐานทำงานได้
ข้อมูลโค้ดต่อไปนี้จะบันทึกเมตริกการกำหนดเวลาเฟรมและส่วนการติดตามที่กำหนดเองสำหรับอินเทอร์เฟซเลย์เอาต์แบบ Lazy ของ Jetpack Compose
@OptIn(ExperimentalMetricApi::class)
@Test
fun scrollComposeList() {
benchmarkRule.measureRepeated(
// [START_EXCLUDE]
packageName = TARGET_PACKAGE,
metrics = listOf(
FrameTimingMetric(),
// Measure power usage. This is supported on Pixel 6 and later.
PowerMetric(PowerMetric.Type.Power(
mapOf(
PowerCategory.CPU to PowerCategoryDisplayLevel.TOTAL,
PowerCategory.DISPLAY to PowerCategoryDisplayLevel.TOTAL,
PowerCategory.GPU to PowerCategoryDisplayLevel.TOTAL,
PowerCategory.NETWORK to PowerCategoryDisplayLevel.TOTAL,
)
)),
// Measure custom trace sections by name EntryRow (which is added to the EntryRow composable).
// Mode.Sum measures combined duration and also how many times it occurred in the trace.
// This way, you can estimate whether a composable recomposes more than it should.
TraceSectionMetric("EntryRowCustomTrace", TraceSectionMetric.Mode.Sum),
// This trace section takes into account the SQL wildcard character %,
// which can find trace sections without the full name.
// This way, you can measure composables produced by the composition tracing
// and measure how long they took and how many times they recomposed.
// WARNING: This metric only shows results when running with composition tracing, otherwise it won't be visible in the outputs.
TraceSectionMetric("%EntryRow%", TraceSectionMetric.Mode.Sum),
),
// Try switching to different compilation modes to see the effect
// it has on frame timing metrics.
compilationMode = CompilationMode.None(),
startupMode = StartupMode.WARM, // restarts activity each iteration
iterations = DEFAULT_ITERATIONS,
// [END_EXCLUDE]
setupBlock = {
uiAutomator {
// Before starting to measure, navigate to the UI to be measured.
startIntent(Intent("$packageName.COMPOSE_ACTIVITY"))
}
}
) {
uiAutomator {
onElement { isScrollable }.fling(Direction.DOWN)
}
}
}
ในตัวอย่างต่อไปนี้ EntryRowCustomTrace แสดงถึงส่วนการติดตามที่กำหนดเองซึ่งกำหนดไว้ภายในเลเยอร์รายการที่สร้างได้โดยใช้ตัวห่อหุ้มบล็อก trace(sectionName) { ... } ของ Kotlin มาตรฐาน หากต้องการระบุข้อมูลสำหรับ TraceSectionMetric คุณต้องรวมคอมโพเนนต์ UI เป้าหมายไว้ภายในตัวห่อหุ้มบล็อก trace ของรันไทม์ Jetpack มาตรฐานในฐานของโค้ดการใช้งานจริงของแอปพลิเคชัน
@Composable
private fun EntryRow(entry: Entry, modifier: Modifier = Modifier) = trace("EntryRowCustomTrace") {
Card(modifier = modifier) {
Row(verticalAlignment = Alignment.CenterVertically) {
Text(
text = entry.contents,
modifier = Modifier
.padding(16.dp)
.wrapContentSize()
)
Spacer(modifier = Modifier.weight(1f))
Checkbox(
checked = false,
onCheckedChange = {},
modifier = Modifier.padding(16.dp)
)
}
}
}
ระบบจะแสดงผลลัพธ์เกณฑ์มาตรฐานไปยังแท็บเทอร์มินัล Benchmark ภายใน Android Studio โดยตรง ดังที่แสดงในรูปที่ 1 หากมีการกำหนดเมตริกหลายรายการ ระบบจะรวมจุดข้อมูลที่คำนวณทั้งหมดไว้ในหน้าต่างสรุป
TraceSectionMetric และ FrameTimingMetric สำหรับเลย์เอาต์ Compose ที่ทันสมัยเราจะอธิบาย StartupTimingMetric, FrameTimingMetric, TraceSectionMetric และ PowerMetric โดยละเอียดด้านล่าง หากต้องการดูรายการเมตริกเกณฑ์มาตรฐานทั้งหมดที่ใช้ได้
โปรดดูคลาสย่อยของ Metric ในข้อมูลอ้างอิง API
StartupTimingMetric
StartupTimingMetric จะบันทึกเมตริกการกำหนดเวลาการเริ่มต้นแอปด้วยค่าต่อไปนี้
timeToInitialDisplayMs: ระยะเวลาตั้งแต่ระบบได้รับ Intent การเปิดแอปจนถึงเวลาที่แสดงผลเฟรมแรกของหน้าจอปลายทางtimeToFullDisplayMs: ระยะเวลาตั้งแต่ระบบได้รับ Intent การเปิดแอปจนถึงเวลาที่แอปรายงานว่าแสดงผลอย่างสมบูรณ์แล้วโดยใช้กลไกการรายงานแพลตฟอร์มภายใน การวัดจะหยุดลงเมื่อแสดงผลเฟรมแรกเสร็จสมบูรณ์หลังจากหรือมีสัญญาณว่าแสดงผลอย่างสมบูรณ์แล้ว
StartupTimingMetric จะแสดงผลค่าต่ำสุด ค่ามัธยฐาน และค่าสูงสุดจากการทำซ้ำการเริ่มต้น หากต้องการประเมินการปรับปรุงการเริ่มต้น ให้มุ่งเน้นที่ค่ามัธยฐานเสมอ เนื่องจากค่าเหล่านี้ให้ค่าประมาณที่ดีที่สุดของเวลาการเริ่มต้นของผู้ใช้ทั่วไป
ในสถาปัตยกรรม Compose-first อย่าพยายามเรียกใช้ activity.reportFullyDrawn ด้วยตนเอง แต่ให้ใช้ยูทิลิตีแบบอะซิงโครนัสที่ปลอดภัยสำหรับ Compose อย่าง ReportDrawn, ReportDrawnWhen หรือ ReportDrawnAfter ภายในคอมโพสได้ของหน้าจอเพื่อส่งสัญญาณไปยัง Macrobenchmark โดยอัตโนมัติเมื่อข้อมูลเครือข่ายแบบอะซิงโครนัสหรือสถานะ UI ที่ซับซ้อนแสดงผลเสร็จแล้ว
ดูข้อมูลเพิ่มเติมเกี่ยวกับการวิเคราะห์และการเพิ่มประสิทธิภาพการเริ่มต้นได้ที่ ดู เวลาการเริ่มต้นแอป
FrameTimingMetric
FrameTimingMetric จะบันทึกข้อมูลการกำหนดเวลาที่แม่นยำจากเฟรมที่สร้างขึ้นโดยการเดินทางของเกณฑ์มาตรฐาน เช่น การเลื่อนรายการหรือภาพเคลื่อนไหวเลย์เอาต์ของ UI ที่ซับซ้อน และแสดงผลค่าการวินิจฉัยต่อไปนี้
frameOverrunMs: ระยะเวลาที่เฟรมหนึ่งๆ เลยกำหนดเวลาที่กำหนด ตัวเลขที่เป็นบวกแสดงถึงเฟรมที่ถูกทิ้งพร้อมกับอาการกระตุกหรือสะดุดที่มองเห็นได้ ตัวเลขที่เป็นลบแสดงถึงความเร็วที่เฟรมเสร็จสมบูรณ์เมื่อเทียบกับกำหนดเวลาของฮาร์ดแวร์ย่อย หมายเหตุ: เมตริกนี้ใช้ได้เฉพาะใน Android 12 (ระดับ API 31) ขึ้นไปframeDurationCpuMs: ระยะเวลาที่เฟรมใช้ในการสร้างบน CPU อย่างต่อเนื่องในทั้งเธรด UI ของแอปพลิเคชันหลักและRenderThreadของ Compose
ระบบจะรวบรวมการวัดเหล่านี้ในการกระจายเปอร์เซ็นไทล์ที่ 50, 90, 95 และ 99
frameDurationCpuMs P50 3.5, P90 6.0, P95 6.4, P99 11.0
frameOverrunMs P50 -11.6, P90 -7.2, P95 -7.1, P99 -1.2
เมื่อเพิ่มประสิทธิภาพลำดับชั้นเลย์เอาต์ Jetpack Compose ให้ดูเฟรมที่มีประสิทธิภาพต่ำที่สุด (ขอบเขต P95 และ P99) หาก frameOverrunMs เพิ่มขึ้นเป็นจำนวนเต็มบวกที่เปอร์เซ็นไทล์สูง แสดงว่าการสร้างใหม่กำลังทำให้เธรดหลักหยุดทำงานระหว่างภาพเคลื่อนไหวการเลื่อนที่หนัก
ดูข้อมูลเชิงลึกเพิ่มเติมเกี่ยวกับการระบุและการแก้ไขเฟรมที่ช้าได้ที่ Jetpack Compose Performance
TraceSectionMetric
TraceSectionMetric จะบันทึกจำนวนครั้งที่ส่วนการติดตามที่เฉพาะเจาะจงเกิดขึ้นและระยะเวลาทั้งหมดที่ใช้ในการดำเนินการ สำหรับการติดตามเวลา เมตริกนี้จะแสดงผลเวลาต่ำสุด เวลาเฉลี่ย และเวลาสูงสุดเป็นมิลลิวินาที ส่วนการติดตามเป้าหมาย
จะกำหนดโดยการเรียกใช้ฟังก์ชันtrace(sectionName)
หรือขอบเขตบล็อกระดับล่างระหว่าง
Trace.beginSection(sectionName) กับ Trace.endSection() หรือตัวแปรแบบอะซิงโครนัส
EntryRowCustomTraceCount min 20.0, median 28.0, max 50.0
EntryRowCustomTraceSumMs min 34.9, median 44.4, max 66.6
โดยค่าเริ่มต้น เมตริกจะแสดงผลเฉพาะส่วนการติดตามที่คอมไพล์โดยตรงจากไบนารีแพ็กเกจแอปพลิเคชันของคุณเอง หากต้องการรวมกระบวนการที่มาจากภายนอกขอบเขตแพ็กเกจของแอป ให้ตั้งค่าพร็อพเพอร์ตี้ targetPackageOnly = false
เมื่อทำงานกับการติดตามรันไทม์ Jetpack Compose คุณสามารถแสดงฟังก์ชันที่สร้างได้แต่ละรายการ ในกราฟการติดตามระบบโดยไม่ต้องเขียนตัวห่อหุ้มการติดตามด้วยตนเอง โดยการเปิดใช้ การติดตามการสร้าง
แม้ว่าการเพิ่มทรัพยากร Dependency androidx.compose.runtime:runtime-tracing ลงในแอปพลิเคชันเป้าหมายจะเพียงพอสำหรับการติดตามโปรไฟล์ด้วยตนเอง แต่การบันทึกการติดตามเหล่านี้แบบเป็นโปรแกรมภายในการเรียกใช้ Macrobenchmark ต้องมีการกำหนดค่าเพิ่มเติมภายในโมดูลเกณฑ์มาตรฐาน
ดูวิธีการตั้งค่าทั้งหมดได้ที่บันทึกการติดตามด้วย Jetpack Macrobenchmark
PowerMetric
PowerMetric จะบันทึกการเปลี่ยนแปลงของกำลังหรือพลังงานตลอดระยะเวลาการเรียกใช้ Macrobenchmark ระบบจะแบ่งหมวดหมู่ที่เลือกแต่ละหมวดหมู่ออกเป็นคอมโพเนนต์ฮาร์ดแวร์ที่วัดได้ ขณะที่หมวดหมู่ที่ไม่ได้เลือกจะจัดกลุ่มไว้ในบัคเก็ต "ไม่ได้เลือก"
ข้อกำหนดของฮาร์ดแวร์: เมตริกเหล่านี้จะวัดการใช้พลังงานทั้งระบบ ไม่ใช่การคำนวณต่อแอป ดังนั้น การเก็บรวบรวมข้อมูลจึงจำกัดไว้เฉพาะอุปกรณ์จริงของ Google Pixel 6, Pixel 6 Pro และอุปกรณ์จริงรุ่นใหม่กว่า
เมตริกจะแสดงผลการวัด 2 รายการต่อหมวดหมู่
power<category>Uw: ปริมาณกำลังที่ใช้ตลอดระยะเวลาการทดสอบใน หมวดหมู่นี้ (วัดเป็นไมโครวัตต์)energy<category>Uws: ปริมาณพลังงานทั้งหมดที่ถ่ายโอนต่อหน่วย เวลาตลอดระยะเวลาการทดสอบในหมวดหมู่นี้ (วัดเป็น ไมโครวัตต์-วินาที)
หมวดหมู่มีดังนี้
CPUDISPLAYGPUGPSMEMORYMACHINE_LEARNINGNETWORKUNCATEGORIZED
ในบางหมวดหมู่ เช่น CPU อาจแยกงานที่กระบวนการอื่นๆ ทำออกจากงานที่แอปของคุณทำได้ยาก ให้นำแอปและบัญชีที่ไม่จำเป็นออกหรือจำกัดการใช้งานเพื่อลดการรบกวน
powerCategoryCpuUw min 300.2, median 346.1, max 519.6
powerCategoryDisplayUw min 319.8, median 325.8, max 329.7
powerCategoryGpuUw min 18.8, median 23.3, max 36.9
powerCategoryNetworkUw min 97.3, median 123.3, max 681.3
powerTotalUw min 1234.8, median 1316.6, max 2112.4
powerUnselectedUw min 483.3, median 512.6, max 561.7
การวิเคราะห์ระบบย่อยหลัก
PowerMetric จะบันทึกการเปลี่ยนแปลงของกำลังหรือพลังงานตลอดระยะเวลาการทดสอบสำหรับหมวดหมู่กำลังที่ระบุ ระบบจะแบ่งหมวดหมู่ที่คุณเลือกแต่ละหมวดหมู่ออกเป็นคอมโพเนนต์ย่อยที่วัดได้ และเพิ่มหมวดหมู่ที่ไม่ได้เลือกไปยังเมตริก "ไม่ได้เลือก"
เอาต์พุตของเทอร์มินัลจะแมปกับการกำหนดค่าที่คุณขอ
powerCategoryCpuUw: ปริมาณกำลังที่ CPU ใช้ตลอดระยะเวลาการทดสอบpowerCategoryGpuUw: ปริมาณกำลังที่ GPU ใช้ตลอดระยะเวลาการทดสอบpowerUnselectedUw: กำลังรวมที่หมวดหมู่ฮาร์ดแวร์ทั้งหมดที่ใช้ได้ใช้ ซึ่งคุณไม่ได้ ขออย่างชัดเจนในแมปการเริ่มต้น
หากต้องการป้องกันไม่ให้ข้อมูลเพิ่มขึ้นอย่างผิดปกติในฮาร์ดแวร์ระหว่างการเรียกใช้ ให้ล็อกความสว่างหน้าจอเป็นค่าคงที่ รักษาอุณหภูมิอุปกรณ์ให้คงที่ และปิดกระบวนการเบื้องหลังที่แข่งขันกันก่อนที่จะเริ่มลูป Macrobenchmark
แหล่งข้อมูลเพิ่มเติม
ดูเนื้อหา
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- สร้างโปรไฟล์พื้นฐาน {:#creating-profile-rules}
- การเขียน Macrobenchmark
- การวิเคราะห์และการเพิ่มประสิทธิภาพการเริ่มต้นแอป {:#app-startup-analysis-optimization}