擷取 Macrobenchmark 指標

指標是指透過效能評定擷取的主要類型資訊。系統會將這些值以 List 的形式傳送至 measureRepeated 函式,您就能一次指定多個評估指標。基準測試需要至少一種指標才能執行。

下列程式碼片段會擷取 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 代表使用標準 Kotlin trace(sectionName) { ... } 區塊包裝函式,在可組合項目層中定義的自訂追蹤區段。如要提供 TraceSectionMetric 的資料,您必須使用標準 Jetpack 執行階段 trace 區塊包裝函式,將目標 UI 元件包裝在應用程式的正式版程式碼中:

@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)
            )
        }
    }
}

基準測試結果會直接輸出到 Android Studio 內的「Benchmark」終端機分頁,如圖 1 所示。如果定義了多項指標,所有計算出的資料點都會合併到摘要視窗。

TraceSectionMetric 和 FrameTimingMetric 的結果。
圖 1. TraceSectionMetricFrameTimingMetric 的合併控制台結果,適用於現代 Compose 版面配置。

下文將詳細說明 StartupTimingMetricFrameTimingMetricTraceSectionMetricPowerMetric。如需可用基準指標的完整清單,請參閱 API 參考資料中的 Metric 子類別。

StartupTimingMetric

StartupTimingMetric 會使用下列值擷取應用程式啟動時間指標:

  • timeToInitialDisplayMs:從系統收到啟動意圖,到轉譯目標畫面第一個影格的時間長度。
  • timeToFullDisplayMs:從系統收到啟動意圖,到應用程式使用內部平台回報機制回報完成繪製的時間長度。發出 (或包含) 完全繪製信號後,測量作業會在第一個影格轉譯完成時停止。

StartupTimingMetric 會從啟動疊代輸出最小值、中位數和最大值。如要評估啟動作業的改善狀況,請一律聚焦在中位數值,因為中位數值能提供一般使用者啟動時間的最佳預測值。

在以 Compose 為優先的架構中,請勿嘗試手動叫用 activity.reportFullyDrawn。請改用畫面 Composable 內的 Compose 安全非同步公用程式 ReportDrawnReportDrawnWhenReportDrawnAfter,在非同步網路資料或複雜的 UI 狀態完成算繪時,自動向 Macrobenchmark 發出信號。

如要進一步瞭解如何分析及最佳化初始化效能,請參閱「應用程式啟動時間」。

FrameTimingMetric

FrameTimingMetric 會從基準測試歷程產生的影格擷取精確的時間資訊,例如捲動清單或複雜的 UI 版面配置動畫,然後輸出下列診斷值:

  • frameOverrunMs:所指定影格錯過期限後的時間長度。正數代表出現掉格,且有可見的卡頓或延遲。負數代表影格提早多少時間於子系統硬體期限前完成。注意:這項指標僅適用於 Android 12 (API 級別 31) 以上版本。
  • frameDurationCpuMs:影格在 CPU 上主動產生時所花費的時間長度,包括主要應用程式 UI 執行緒和 Compose RenderThread

測量結果採計分布在第 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 效能」。

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 執行階段追蹤功能時,只要啟用組合追蹤,即可在系統追蹤圖表中顯示個別可組合函式,不必手動編寫追蹤包裝函式。

androidx.compose.runtime:runtime-tracing 依附元件新增至目標應用程式,就足以進行手動剖析器追蹤,但如要在 Macrobenchmark 執行期間以程式輔助方式擷取這些追蹤記錄,則需要在基準測試模組中進行額外設定。

如需完整設定操作說明,請參閱「使用 Jetpack Macrobenchmark 擷取追蹤記錄」。

PowerMetric

PowerMetric 會擷取 Macrobenchmark 執行期間的電量或能量變化。每個選取的類別都會細分為可測量的硬體元件,未選取的類別則會歸入「未選取」類別。

硬體需求:這些指標測量的是整個系統的耗電量,而非個別應用程式的耗電量。因此,資料收集僅限於實體 Google Pixel 6、Pixel 6 Pro 和更新的實體裝置。

這項指標會針對每個類別輸出兩項評估結果:

  • power<category>Uw:這個類別在測試期間的耗電量 (以微瓦為單位)。
  • energy<category>Uws:這個類別在測試期間每單位時間所轉移的總能量 (以微瓦秒為單位)。

類別如下:

  • CPU
  • DISPLAY
  • GPU
  • GPS
  • MEMORY
  • MACHINE_LEARNING
  • NETWORK
  • UNCATEGORIZED

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 迴圈前關閉競爭的背景程序。

其他資源

Views content