这一重大发布带来了稳定的基准配置文件, 新的基准测试模式, 完整的trace功能等.
Jetpack 基准库提供了一套工具, 用于在受控环境中检查和改进应用程序性能.
这些实验室测试可以使用Macrobenchmark检查整个端到端用户流, 也可以使用Microbenchmark检查循环中的实施细节.
Macrobenchmark还可用于生成基线配置文件和启动配置文件. 两者都有助于提高应用程序性能.
所有这些功能都由androidx.benchmark库组提供. 尽管版本从 1.1.1 升级到了 1.2.0, 但还是增加了很多新功能. 让我们深入了解一下 Jetpack Benchmark 1.2.0 的新功能.
基准配置文件中的新功能
基线配置文件通过提前编译避免了解释和类初始化的成本, 从而将包含路径的整体代码执行速度提高了约 30%.
这些配置文件已经存在了一段时间, Google Play 商店中的许多应用程序和游戏都已使用.库也可以贡献基线配置文件, 无缝提高应用程序性能. 有了新的 Gradle 插件, 自动生成基线配置文件变得前所未有的简单.
✨ 基线配置文件 API 现已稳定 ✨
随着 Benchmark 1.2.0 版本的发布, 基线配置文件不再是试验性的.
在 Benchmark 1.1.0 中, 当基线配置文件作为实验性功能被引入时, 它与collectBaselineProfileAPI 一起发布. 它被更简单的collect API 所取代. You 现在可以生成稳定的基线配置文件, 并使用UiAutomator捕获用户旅程作为配置文件的一部分.
class BaselineProfileGenerator {
@get:Rule
val baselineProfileRule = BaselineProfileRule()
@Test
fun appStartupAndUserJourneys() {
baselineProfileRule.collect(packageName = PACKAGE_NAME) {
// App startup journey.
startActivityAndWait()
device.findObject(By.text("For You")).clickAndWait(Until.newWindow(), 1_000)
device.findObject(By.res("myLazyColumn")).also {
it.fling(Direction.DOWN)
it.fling(Direction.UP)
}
}
}
}
以上代码收集了应用程序启动时的基线配置文件和用户旅程, 其中UiAutomator用于查找"For You"文本, 点击它然后向下和向上滚动一列.
使用 Android Studio Canary 设置基线配置文件模块
我们正在改进基线配置文件的设置体验. Android Studio Iguana Canary 版本中提供了这种新体验.
Android Studio 基线配置文件生成器模块模板可自动创建一个新模块, 用于生成和基准测试基线配置文件. 运行该模板可生成大部分典型的构建配置, 基线配置文件生成和验证代码. 该模板可创建生成基线配置文件并对其进行基准测试的代码. 这有助于改进和测量应用程序的启动时间.
创建新模块并选择"Baseline Profile Generator", 进入对话框并点击完成.
现在, 你可以直接从 Android Studio 的运行对话框中生成基线配置文件.
使用 Gradle 插件自动生成基线配置文件
实施基线配置文件的开发人员提出的一个优先功能要求是帮助他们自动完成这一过程.
在使用 AGP 8.0 或更新版本时, 你现在可以使用Baseline Profile Gradle 插件. 该插件可让你完全控制基线配置文件的创建. 它将配置文件生成无缝集成到 Gradle 构建管道中. 你可以控制配置文件的更新时间, 确保新版本中的配置文件始终是最新的.
baselineProfile {
variants {
freeRelease {
automaticGenerationDuringBuild = true
}
}
}
要使用 Gradle 插件, 请将其应用到应用程序和基线配置文件模块中. 你可以根据指南手动操作, 也可以使用 Android Studio Iguana 为基线配置文件提供的新模块模板. 该插件提供广泛的配置选项, 具有很高的灵活性. 你可以使用 Gradle 管理的设备, 以方便在 CI 系统上运行. 使用 Gradle 插件时, baseline-prof.txt源文件不必再作为应用程序源代码集的一部分. 它们可被视为可重复生成的代码.
简化配置文件过滤, 增强复杂应用程序和库开发人员的能力
大型代码库或程序库需要过滤机制, 以便在基线配置文件中只包含特定的类. Gradle 插件就提供了这样的功能. 新的过滤块可通过正则表达式包含或排除代码.
baselineProfile {
filter {
include("com.myawesomelibrary.widget.grid.**")
exclude("com.myawesomelibrary.widget.grid.debug.**")
}
}
Macrobenchmark 中的新功能
改进基准测试的参数
新的剖析模式
Macrobenchmark现在提供了方法trace和堆栈采样模式..
有了这些剖析模式, 你可以获得正在执行的代码特定区域的详细信息. 要启用这些模式, 请在使用StackSampling或MethodTracing参数时使用androidx.benchmark.profiling.mode参数.
使用MethodTracing, 你可以查看代码块执行时到底调用了哪些方法. 这有助于一目了然地确定应用程序是否在做你期望它做的事情.
StackSampling会突出显示基准在所有调用堆栈中花费时间的地方. 有了它, 你就可以看到应用程序在运行过程中花费时间最多的地方.
⚠️
注意: 这两种模式会使性能指标出现偏差. 你可以依靠它们查看运行时的情况, 但在启用方法trace或堆栈采样时, 请谨慎对待帧计时或启动结果.
⚠️
通过dry run进行快速验证
使用dryRunMode.enable仪器参数可加快验证速度. 这对预提交环境或基准开发期间非常有用, 并将标记从 Microbenchmark 升级到 Macrobenchmark.
使用 Perfetto Sdk trace以获得更高分辨率的指标
要在基准测试时获得更多细节, 你可以使用 Perfetto Sdk Tracing trace应用程序的行为. 虽然这会在应用程序运行时加载一个库, 并减慢StartupMode.COLD基准的运行速度, 但它确实能让你更详细, 更全面地了解基准运行时发生的情况. 当你怀疑有常规trace无法发现的需要改进的地方时, 这将非常有用.
要启用 Perfetto Sdk trace功能, 请将这些依赖项添加到基准模块中,
implementation("androidx.tracing:tracing-perfetto:1.0.0-beta01")
implementation("androidx.tracing:tracing-perfetto-binary:1.0.0-beta01")
并使用perfettoSdkTracing.enable仪器参数运行基准.
利用新的实验指标获得更多洞察力
Macrobenchmark 库中的新指标可让你更深入地了解数据, 并进一步增强自动监控功能.
使用 PerfettoTraceProcessor 开启任何进程
PerfettoTraceProcessor API将基准结果中的每个细节都整合到一个API中. 它非常灵活, 支持同步和异步trace区域, 内核级调度时序, binder事件以及 Perfetto trace中捕获的其他任何内容.
现在, 你可以在宏基准中使用相同的trace查询 API. 这对于创建自己的完全自定义TraceMetric尤为有用.
使用 TraceSectionMetric 和 TraceMetric 呈现更多细节
这些特定于trace的 API 可快速处理应用程序的特定部分和trace.
使用TraceSectionMetric可以捕获应用程序中的自定义trace部分. 例如, 你可以使用TraceSectionMetric来捕获活动启动过程中特定部分所需的时间. 本示例展示了如何收集 onStart 和 onResume 方法的持续时间. 此外, 下面的示例通过使用Mode.Sum捕获 doFrame trace, 汇总了渲染帧所需的时间.
private fun startup(compilationMode: CompilationMode) = benchmarkRule.measureRepeated(
packageName = PACKAGE_NAME,
metrics = listOf(
StartupTimingMetric(),
TraceSectionMetric("activityStart", Mode.First),
TraceSectionMetric("activityResume", Mode.First),
TraceSectionMetric("Choreographer#doFrame %", Mode.Sum),
),
compilationMode = compilationMode,
startupMode = startupMode,
) {
startActivityAndWait()
forYouWaitForContent()
}
这些指标都是基准测试结果的一部分, 有助于确定优化的方向, 并监控潜在的性能下降.
上述代码段的度量结果
Macrobenchmark 现在还提供了新的TraceMetric API, 可让你从宏基准数据中创建自己的复杂度量, 因为它可让你针对 Perfetto trace运行任意查询. 你可以获取基准运行期间 Perfetto trace中捕获的任何数据, 并将其转化为度量指标. 有关如何使用可用数据的更多信息, 请参阅Perfetto 文档.
使用 PowerMetric 了解功耗
PowerMetric可捕捉指定时间内功率, 能量或电池电量指标随时间的变化.
当在带电源轨(如 Pixel 6 或更新版本)的设备上运行时, 该指标会提供电池, 能量和电量的详细信息.
有了这些信息, 你就可以验证应用程序特定部分对资源的需求程度, 或不同 API(如位置服务)的轮询间隔对电池电量的影响. 你甚至还可以查看动画或黑暗模式对功耗的影响, 并调整应用程序在 AMOLED 或 OLED 等不同显示屏类型上的省电方式.
微基准测试中的新功能
剖析微基准测试非常重要, 因此我们使剖析迭代循环更快, 可配置性更强. 现在, 在收集所有指标后, 剖析作为微基准中的一个单独阶段运行, 因此你可以同时看到剖析结果和测量结果, 或在 CI 中连续运行剖析.
我们还添加了一个实验性 API, 让你在迭代微基准时在代码中选择剖析器. 该实验性 API 可让你配置trace, 例如启用自定义的trace()部分, 该部分在 micro 中默认关闭, 以避免干扰shouldEnableAppTagTracing.
从内部配置微基准测试行为
使用MicrobenchmarkConfig, 你可以配置捕获基准的方式, 而无需依赖instrumentation参数.
这样就可以配置剖析或trace行为, 这意味着你可以根据基准规则启用trace应用程序标签或 perfetto sdk trace.
@OptIn(ExperimentalBenchmarkConfigApi::class)
@get:Rule
val benchmarkRule = BenchmarkRule(
MicrobenchmarkConfig(shouldEnableTraceAppTag = true, shouldEnablePerfettoSdkTracing = true)
)
启用这些功能后, 你会在基准结果中看到一个新的"Trace"和"Stack Sampling Trace"链接, 可以使用 Android Studio Profilers 检查这些结果.
要启用trace功能, 需要在微基准测试中添加对 perfetto tracing库和 perfetto binary库的依赖. 否则将导致运行时异常.
java.lang.RuntimeException:
Issue while enabling Perfetto SDK tracing in com.example.benchmark.test:
Error:
Unable to locate libtracing_perfetto.so required to enable Perfetto SDK.
Tried inside /data/app/com.example.benchmark.test/base.apk.
无需 JUnit 即可控制基准状态
BenchmarkState允许在不依赖 JUnit API 的情况下查询基准的状态. 有了它, 你可以实例化 BenchmarkState, 这在不使用 JUnit4 时特别有用.
捕捉和自定义 Perfetto trace
PerfettoTraceRule可帮助你详细分析测试性能. 使用PerfettoTrace.record时, 你可以编写基于trace的单元测试, 或在 Perfetto trace之上创建自己的测试基础架构.
性能优化和bug修复
除了所有这些新功能, 我们还修复了错误, 并提高了库组的性能. 要了解1.1.1和1.2.0之间的所有变化, 请阅读发布说明.