Benchmark 与 Macrobenchmark:先选测量边界 · AndroidX 源码指南
AAndroidX 源码指南
测试与性能
测试与性能 · androidx.test

Benchmark 与 Macrobenchmark:先选测量边界

区分进程内小代码测量与跨进程完整用户流程。

最后更新 2026-08-01

复制即用

Microbenchmark(同模块/进程,小代码边界):

@get:Rule
val benchmarkRule = BenchmarkRule()

@Test
fun parseDocument() = benchmarkRule.measureRepeated {
    parser.parse(source)
}

Macrobenchmark(独立 APK 驱动完整流程):

@get:Rule
val benchmarkRule = MacrobenchmarkRule()

@Test
fun coldStart() = benchmarkRule.measureRepeated(
    packageName = "com.example.app",
    metrics = listOf(StartupTimingMetric()),
    iterations = 10,
    startupMode = StartupMode.COLD,
    setupBlock = { pressHome() },
) {
    startActivityAndWait()
}

两种 Benchmark 对比

维度MicrobenchmarkMacrobenchmark
进程与测试代码同模块/进程独立测试 APK 驱动目标应用
适合算法、布局计算、序列化启动、滚动、帧时间、完整路径
度量BenchmarkRule.measureRepeatedMacrobenchmarkRule + Metrics
噪声控制环境隔离Release/profileable、物理设备、固定温控

常用 Metrics

Metric用途
StartupTimingMetric冷/温/热启动时间
FrameTimingMetric帧时间(滚动流畅度)
TraceSectionMetric指定 trace section 耗时
MemoryUsageMetric内存占用
fun scrollTest() = benchmarkRule.measureRepeated(
    packageName = "com.example.app",
    metrics = listOf(FrameTimingMetric(), TraceSectionMetric("MySection")),
    iterations = 10,
    startupMode = StartupMode.WARM,
) {
    startActivityAndWait()
    device.executeShellCommand("input swipe 500 1500 500 300 100")
}

常见陷阱

  • 微基准塞网络/磁盘:环境噪声大于真正差异。
  • 无意义迭代次数:Release/profileable 构建、物理设备、固定温控比 iteration 更重要。
  • measure block 混入前置操作setupBlock 只建状态,measure 只计时。
  • 模拟器跑基准:性能数据无参考价值。

要点

  • 先选测量边界:小代码微基准,完整流程宏基准。
  • setupBlock 建前置状态;measure block 只保留要计时的行为。
  • Release/profileable + 物理设备 + 固定温控决定结果可信度。
  • 帧时间/启动/内存分别用对应 Metric。

相关页面