Metrik adalah jenis informasi utama yang diekstrak dari benchmark Anda. Metrik
diteruskan ke fungsi measureRepeated sebagai List, yang memungkinkan Anda
menentukan beberapa metrik terukur sekaligus. Setidaknya satu jenis metrik diperlukan agar benchmark dapat dijalankan.
Cuplikan kode berikut menangkap waktu render frame dan metrik bagian rekaman aktivitas kustom untuk antarmuka tata letak lambat 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)
}
}
}
Dalam contoh berikut, EntryRowCustomTrace mewakili bagian trace kustom
yang ditentukan di dalam lapisan item composable menggunakan wrapper blok
trace(sectionName) { ... } Kotlin standar. Untuk menyediakan data bagi
TraceSectionMetric, Anda harus menggabungkan komponen UI target di dalam
codebase produksi aplikasi dengan wrapper blok trace
runtime Jetpack standar:
@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)
)
}
}
}
Hasil benchmark adalah output langsung ke tab terminal Benchmark di dalam Android Studio, seperti yang ditunjukkan pada Gambar 1. Jika beberapa metrik ditentukan, semua titik data yang dihitung akan digabungkan di jendela ringkasan.
TraceSectionMetric dan FrameTimingMetric untuk tata letak Compose modern.StartupTimingMetric, FrameTimingMetric, TraceSectionMetric, dan
PowerMetric dibahas secara mendetail di bawah. Untuk mengetahui daftar lengkap metrik tolok ukur yang tersedia, lihat subclass Metric di referensi API.
StartupTimingMetric
StartupTimingMetric mengambil metrik pengaturan waktu startup aplikasi dengan nilai
berikut:
timeToInitialDisplayMs: Jumlah waktu sejak sistem menerima intent peluncuran hingga saat sistem merender frame pertama layar tujuan.timeToFullDisplayMs: Jumlah waktu sejak sistem menerima intent peluncuran hingga saat laporan aplikasi sepenuhnya digambar menggunakan mekanisme pelaporan platform internal. Pengukuran berhenti saat rendering frame pertama selesai setelah, atau berisi, sinyal yang digambar sepenuhnya.
StartupTimingMetric menghasilkan nilai minimum, median, dan maksimum dari iterasi startup. Untuk menilai peningkatan startup, selalu fokus pada nilai median, karena nilai median memberikan perkiraan terbaik dari waktu startup pengguna biasa.
Dalam arsitektur Compose-first, jangan mencoba memanggil
activity.reportFullyDrawn secara manual. Sebagai gantinya, gunakan utilitas asinkron yang aman untuk Compose, yaitu
ReportDrawn, ReportDrawnWhen, atau ReportDrawnAfter
di dalam composable layar untuk otomatis memberi sinyal ke Macrobenchmark saat
data jaringan asinkron atau status UI yang kompleks telah selesai dirender.
Untuk mengetahui informasi selengkapnya tentang cara menganalisis dan mengoptimalkan performa inisialisasi, lihat Waktu startup aplikasi.
FrameTimingMetric
FrameTimingMetric menangkap informasi pengaturan waktu yang akurat dari frame
yang dihasilkan oleh perjalanan benchmark, seperti men-scroll daftar atau animasi tata letak UI
yang kompleks, dan menghasilkan nilai diagnostik berikut:
frameOverrunMs: jumlah waktu ketika frame tertentu melewati batas waktu. Angka positif menunjukkan penurunan frame yang disertai dengan jank atau kondisi tersendat yang terlihat. Angka negatif menunjukkan seberapa cepat frame selesai dibandingkan dengan batas waktu hardware subsistem. Catatan: Metrik ini hanya tersedia di Android 12 (level API 31) dan yang lebih baru.frameDurationCpuMs: jumlah waktu yang dihabiskan frame untuk diproduksi secara aktif di CPU di UI thread aplikasi utama danRenderThreadCompose.
Pengukuran ini dikumpulkan dalam distribusi persentil ke-50, ke-90, ke-95, dan ke-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
Saat mengoptimalkan hierarki tata letak Jetpack Compose, lihat
frame dengan performa terburuk (batas P95 dan P99). Jika frameOverrunMs melonjak
menjadi bilangan bulat positif pada persentil tinggi, hal ini menunjukkan bahwa rekomposisi
menghambat thread utama selama animasi scroll yang berat.
Untuk mendapatkan insight yang lebih mendalam tentang cara mengidentifikasi dan menyelesaikan frame lambat, lihat Performa Jetpack Compose.
TraceSectionMetric
TraceSectionMetric mencatat berapa kali bagian rekaman aktivitas tertentu
muncul dan jumlah waktu absolut yang diperlukan untuk mengeksekusinya. Untuk pelacakan waktu,
class ini menghasilkan waktu minimum, median, dan maksimum dalam milidetik. Bagian rekaman aktivitas
target ditentukan oleh panggilan fungsi trace(sectionName)
atau batas blok tingkat lebih rendah antara
Trace.beginSection(sectionName) dan Trace.endSection() atau
varian asinkronnya.
EntryRowCustomTraceCount min 20.0, median 28.0, max 50.0
EntryRowCustomTraceSumMs min 34.9, median 44.4, max 66.6
Secara default, metrik hanya menghasilkan bagian rekaman aktivitas yang dikompilasi langsung dari biner paket aplikasi Anda sendiri. Untuk menyertakan proses yang berasal dari luar
batas paket aplikasi Anda, tetapkan properti targetPackageOnly = false.
Saat mengerjakan Pelacakan Runtime Jetpack Compose, Anda dapat menampilkan setiap fungsi composable dalam grafik pelacakan sistem tanpa menulis wrapper pelacakan manual dengan mengaktifkan pelacakan komposisi.
Meskipun menambahkan dependensi androidx.compose.runtime:runtime-tracing ke
aplikasi target sudah cukup untuk pelacakan profiler manual, menangkap pelacakan
ini secara terprogram dalam operasi Macrobenchmark memerlukan konfigurasi
tambahan di dalam modul benchmark Anda.
Untuk mengetahui petunjuk penyiapan lengkap, lihat Merekam aktivitas dengan Jetpack Macrobenchmark.
PowerMetric
PowerMetric merekam perubahan daya atau energi selama durasi
eksekusi Macrobenchmark Anda. Setiap kategori yang dipilih dibagi menjadi komponen hardware terukur, sedangkan kategori yang tidak dipilih dikelompokkan ke dalam bucket "unselected".
Persyaratan Hardware: Metrik ini mengukur konsumsi seluruh sistem, bukan penghitungan per aplikasi. Oleh karena itu, pengumpulan data dibatasi untuk perangkat fisik Google Pixel 6, Pixel 6 Pro, dan perangkat fisik yang lebih baru.
Metrik ini menghasilkan dua pengukuran per kategori:
power<category>Uw: jumlah daya yang dikonsumsi selama durasi pengujian dalam kategori ini (diukur dalam mikrowatt).energy<category>Uws: jumlah total energi yang ditransfer per unit waktu selama durasi pengujian dalam kategori ini (diukur dalam mikrowatt-detik).
Kategori mencakup:
CPUDISPLAYGPUGPSMEMORYMACHINE_LEARNINGNETWORKUNCATEGORIZED
Dengan beberapa kategori, seperti CPU, mungkin sulit untuk memisahkan pekerjaan yang dilakukan oleh
proses lain dari pekerjaan yang dilakukan oleh aplikasi Anda sendiri. Untuk meminimalkan gangguan,
hapus atau batasi aplikasi dan akun yang tidak diperlukan.
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
Menganalisis subsistem inti
PowerMetric merekam perubahan daya atau energi selama durasi pengujian untuk kategori daya yang disediakan. Setiap kategori yang Anda pilih dibagi menjadi subkomponen terukur, dan kategori yang tidak dipilih ditambahkan ke metrik "unselected".
Output terminal dipetakan ke konfigurasi yang Anda minta:
powerCategoryCpuUw: Jumlah daya yang dikonsumsi oleh CPU selama durasi pengujian.powerCategoryGpuUw: Jumlah daya yang dikonsumsi oleh GPU selama durasi pengujian Anda.powerUnselectedUw: Daya gabungan yang dikonsumsi oleh semua kategori hardware yang tersedia yang tidak diminta secara eksplisit dalam peta inisialisasi Anda.
Untuk mencegah lonjakan data yang tidak menentu pada rel hardware selama proses berjalan, kunci kecerahan layar ke nilai tetap, pertahankan suhu perangkat yang stabil, dan tutup proses latar belakang yang bersaing sebelum memulai loop Macrobenchmark.
Referensi lainnya
Konten penayangan
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Membuat Profil Dasar Pengukuran {:#creating-profile-rules}
- Menulis Macrobenchmark
- Analisis dan pengoptimalan startup aplikasi {:#app-startup-analysis-optimization}