性能优化的重要性和难度毋庸置疑,事实上,性能优化也是一个永无止境的游戏,总会发现有一些东西需要优化。但是不可避免的是,这也是一个边际效益递减的事情,项目或应用获得的收益在一定程度上也会逐渐降低。What’s new in next generation Android Performance?在现在的手机红海市场,不只是硬件越发同质化,软件(Android + Linux Kernel)在创新方面也渐渐放缓的脚步。作为手机用户,你最看重的手机哪个特性,性能、稳定性、安全、续航或其他?今天我们来分析和展望下一代Android 性能所需具备的特点。
在最新的Google I/O 2023大会上,Pichai着重强调了All in AI的趋势。在过去的几年里,Android一直在努力使工作变得更加简单和有益,在Baseline Profiles、Android Studio、libraries 等方面有了进一步的改进优化,因而提供了更好的启动性能改进。
Baseline Profiles
通过避免即时(JIT)编译,将应用程序启动和运行时的代码执行速度提高了大约30%。通过构建工具来简化Baseline Profiles文件的创建和维护,包括一个新的Android Studio模板和Gradle插件。
使用Baseline profile Gradle Plugin简化概要文件生成
Gradle Plugin使得在本地开发和CI期间生成和维护基线配置文件变得更加容易。它执行生成基线概要文件并将其安装到应用程序模块中的所有必要步骤。要使用该插件,需要在项目中添加一个instrumented test module,并定义一组测试,用于在应用中跟踪流程,以模拟关键的用户进程。当运行instrumented test module时,Gradle Plugin会跟踪在这些用户进程中执行的所有类和方法,并基于这些类和方法生成Baseline Profiles,然后将生成的Baseline Profiles文件复制到应用程序模块的源代码中。
在应用插件后,可以在构建的脚本中使用新的BaselineProfile块对其进行配置,GenerateBaselineProfile Gradle任务运行所有BaselineProfile文件测试,生成的BaselineProfile文件存储在生成的文件夹中。这些特性消除了在本地和远程CI服务器上自动生成BaselineProfile的gap。通过指定在生成BaselineProfile时使用的Gradle Managed Device,甚至不需要附加物理设备。
详细内容可以查看测试用例代码和Guide Docs来进一步学习和实践。
使用AGP 8+创建和管理多个Baseline Profile源文件
AGP 8以后支持多个源文件、特定于变体的BaselineProfile,并支持上面提到的新的Gradle插件。目前默认位置是src/main/baselineProfiles/,存储在此目录中的Baseline Profile源文件将被提取并合并到应用程序中,这也使得能够为应用程序中各个线程存储单独的配置文件。
Android Studio基线配置文件生成器模板
为了帮助开发者快速上手使用BaselineProfile,Android Studio Hedgehog(2023.1.1)添加了BaselineProfile生成器模块向导模板。通过使用这个模板,你的应用可以用一种视觉辅助的方式设置BaselineProfile。
具体路径为:File > New > New Module,并从模板列表中选择Baseline Profile Generator。
这个模块创建了一个包含基本生成器和基准的新的Baseline Profile测试模块。BaselineProfileGenerator类为您创建了一个基本的配置文件,startupbenchmark可以验证一切正常工作。此外,Gradle插件将在相关模块中应用。最后,为了应对Android的依赖,将添加Profileinstaller,以帮助本地验证和向后兼容性。
从这里开始,所需要做的就是执行Generate Baseline Profile运行配置,该配置运行包括Baseline Profile生成器,并将生成的概要文件复制到src/release/generated/baselineProfile。
运行配置调用:app:generateBaselineProfile任务,查找所有Baseline Profile生成器并运行。
BaselineProfileGenerator只启动应用程序并等待应用程序启动完成,所以官方建议为应用中的每个关键用户线程创建基线配置文件。
启动配置文件和Dex布局优化
从8.1版本开始,Android Gradle Plugin (AGP)可以将应用程序启动所需的代码拉入应用程序的主索引文件中,这种优化称为索引布局优化,有助于减少应用程序启动期间的索引页面错误。这可以显著加快应用程序的启动速度,因为在应用程序完成启动之前,只需要加载一个索引文件。
虽然AGP可以为应用程序创建单独的索引文件,但如果没有开发者自定义,它仍然不知道如何定义应用程序的启动,这就是启动配置文件的用武之地。你可以把启动配置文件看作是Baseline Profile的一个子集,它是专门为应用程序启动量身定制的。两者共享相同的格式并使用相同的底层技术。由于每个应用程序的启动都是不同的,所以libraries 不会对启动配置文件做出定制化。
与需要解释和JIT编译的应用程序(例如,在推送更新之后)相比,Baseline Profile提供了大约30%的性能提升。目前对Dex布局优化的早期测试显示,在应用程序启动时,在基线配置文件收益的基础上,性能又提高了30%。
为了充分利用Dex布局优化和启动配置文件,开发者需要让Android框架知道你的应用程序何时启动完成。如果开发者什么都不做,那么在绘制第一帧时,应用程序启动将被视为完成。要确保启动配置文件包含用户可以接管的信息,请使用reportFullyDrawn api。你可以通过FullyDrawnReporter或者Compose ReportDrawn api来实现。此外,需要在开发者认为启动完成的位置为启动基准定义终点。将对reportFullyDrawn的调用与期望在应用准备使用时显示在屏幕上的内容相匹配。
可以进一步查看Dex layout优化文档,对你的应用程序进行分析和优化。
Macrobenchmark库的新功能
Macrobenchmark够全面精准的测量Android应用程序性能,创建Baseline Profile并监控应用程序的更改是否会对应用程序性能产生影响,目前的1.2.0将很快升级为测试版,以下是一些功能亮点:
1、在基准测试中使用新的Android平台特性
从Android 13及更新版本开始,可以在非root设备或模拟器上使用BaselineProfileRule生成基线配置文件。从Android 14及更新版本开始,目标应用程序不再需要在基准测试运行之间重新安装。这使得应用程序可以保存状态,比如缓存、会话状态或登录令牌。
2、新API
当使用collectBaselineProfile方法创建基线配置文件时,可以从代码中删除 test API注释的选项。但是如果想继续使用实验性的API,可以有新API供考虑。这个API就是新引入的collectStableBaselineProfile,它开始运行并等待,直到一个Baseline Profile对于给定的迭代量被认为是稳定的。这意味着你的应用程序的Baseline Profile将更好地反映代码路径执行时应用程序中发生的事情。
@OptIn(ExperimentalStableBaselineProfilesApi::class)
@Test
fun profileGenerator() {
rule.collectStableBaselineProfile(
packageName = TARGET_PACKAGE,
maxIterations = 10
) {
profileBlock()
}
}
3、更强大的指标与自定义跟踪处理
PerfettoTraceRule支持在基准测试之外的测试中自定义跟踪收集(需要API 23+)。这是一个强大的功能,允许用户收集有关测试的性能和计时数据。
PerfettoTraceProcessor支持查询跟踪内容,并且是所有现有Macrobenchmark Metric api背后的引擎。现在可以将它与TraceMetric一起使用,以与Macrobenchmark从Perfetto系统跟踪中的任何信息中使用相同的方式来定义完全自定义的指标。这是另一个强大的特性,允许用户进一步定制他们的基准测试。
4、根据benchmarks计算功耗
新的PowerMetric API可用于测量能耗和功率状态,即允许用户跟踪benchmarks的能耗。
5、Bug修复和其他改进
Macrobenchmark团队还对人体工程学进行了各种其他改进,修复了错误并改进了整体行为。要了解更多信息,请查看文档。如果想了解更多细节,可以在这里找到一个完整的发布说明列表,附带代码和跟踪issues。
Android Studio Power Profiler
Android Studio Hedgehog提供了一个新的Profiler,可以显示物理设备上的功耗,并按每个子系统进行细分(例如:相机、GPS等)。这些数据在记录系统Tracing时非常有用,并直观地将设备的功耗与应用程序中发生的操作关联起来。例如,可以A /B测试批量API调用,而不是进行单独的API调用,以优化相关功耗。使用Pixel 6+设备记录系统Traing并将其加载到Android Studio,或使用分析器直接从附加设备捕获系统Tracing。详细案例在此处
性能、性能还是性能
我们为什么要如此关注系统性能,不论是Android还是Linux Kernel?因为这是影响用户体验最关键的部分,尤其是在手机场景下,对于用户来说,快速响应的应用意味着更好的用户体验。对于企业来讲,性能优越的产品也是核心价值,可以产生技术壁垒,增强产品竞争力。
在研究性能时,找到正确的起点是一个巨大的挑战。基于eBPF和AI等其他手段,从Linux kernel到Android APP全链路打通,从可观测性的角度,逐步趋近于云原生、服务器等领域的APM框架,这也是未来的一个发展方向。
性能优化,道阻且长,吾辈需持续努力!