服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

Baseline Profiles 在 Compose 中的应用 | 开发者说·DTalk

日期: 来源:Android 开发者收集编辑:codelang

本文原作者: codelang原文发布于: 扣浪


为什么需要 Baseline Profiles?


应用启动运行时解释执行 (JIT) 代码,并将热点代码翻译为机器代码,此过程需要时间,因此会降低性能,那 Baseline Profiles 是做什么的呢?就是将原本运行时解释执行的热点代码提前准备好,在应用处于空闲时,可以直接将热点代码编译成机器代码,这时在下次运行时可被直接执行,省去了运行时解释代码的过程,为应用启动提升性能。

如下是官方使用 Baseline Profiles 在应用启动上提升的百分比,来自《Performance best practices for Jetpack Compose》: 
https://www.youtube.com/watch?v=EOQB8PTLkpY&ab_channel=AndroidDevelopers

官方提供的数据非常吸引人,但具体落地到项目中是否能和 Google 提供的数据差不多还需要自测。



Baseline Profiles 流程图



△ 从编写、编译到安装的整体流程图

本流程图更专注于 Baseline Profiles 在开发层面的执行过程,像官方罗列的 Cloud 部分,本文不阐述。


接下来,我们来讲述这三个部分。


编写时


在官方文档中有介绍如何通过 Macrobenchmark 来获取自己项目的 baselie-profile.txt,但需要注意的是,该方式需要准备一台 Android 9 及其以上 root 过的手机。


  • baselie-profile.txt
    https://developer.android.google.cn/topic/performance/baselineprofiles#creating-profile-rules



既然是文本文件的话,那是不是我们自己也可以手动去写?答案是的,但不是很建议,因为项目代码一直在变,手动录入的话会导致维护困难,官方有列出 baseline-profile 的格式: 

具体的规则可以查看官方的 Rule syntax 章节,接下来,我们需要探索下 Compose 项目中,这个文件是放置在哪的。

  • Rule syntax
    https://developer.android.google.cn/topic/performance/baselineprofiles#rule_syntax



稍微改了下 checkPlugin 插件,只打印 aar 中含有 baseline-prof.txt 文件的依赖: 
list.forEach { path ->    ...    while (zipInputStream.nextEntry.also { ze = it } != null) {        if (ze!!.isDirectory) {            continue        }        // 打印 aar 里面含 baseline-prof.txt 的依赖      .if(ze!!.name == "baseline-prof.txt"){            println(path+" --> name="+ze!!.name)        }    }    zipInputStream.closeEntry()    input.close()}
  • checkPlugin
https://github.com/MRwangqi/pluginDemo

打印结果如下: 

从结果上看,Compose 相关的依赖基本都含有一份自己的 baseline-profile.txt 文件,我们看下 compose.ui 的 baseline-profile.txt,看到了熟悉的 AndroidComposeView: 

baseline-profile.txt 在模块目录中的结构如下,与 AndroidManifest.xml 同级: 


编译时

在编译阶段,AGP 会将所有依赖的 baseline-profile.txt 合并成一个文件,然后编译输出 baseline.prof 文件。

从 AGP 7.0 源码来看,最主要的两个 task 为 CompileArtProfileTask 和 MergeArtProfileTask,我们对这两个 task 简单的跟踪下: 

这个地方可以注意一下这个判断,如果不想启用 ArtProfile task 的话,可以设置 android.enableArtProfiles 为 false,或者 deuggable 设置成 true。


MergeArtProfileTask

获取所有模块的 baseline-profile.txt 文件: 

然后将所有模块的 baseline-profile.txt 内容进行合并: 

合并很简单,就是将所有的文件内容汇总写入到 outputFile 里,我们来看下这个最终输出的文件: 


CompileArtProfileTask

编译解析合并后的 baseline-profile.txt 中的规则,具体可以看该 Task 下的 HumanReadableProfile 类,将提取出来的规则与 DexFile 比对,找出匹配的访问标识、profile method 和 profile class 存储到 profileData 中,最终用 ArtProfile 包裹起来 save 到 baseline.prof 中,这个地方的写入是有格式的 (例如魔数),具体可以看 ArtProfileSerializer,下面贴个图: 

所以,如果 baseline-profile.txt 文件描述的类和方法与实际的 class 不一致的话,则不会参与最终的 profile 优化,因为会被剔除掉,这个需要注意。


baseline.prof 的产物如下: 

最终打包的时候,会将该文件添加到 assets/dexopt 目录下参与打包,打包效果: 

如何检查自己的 AGP 是否支持 Baseline Profiles 的打包呢 (前提是打非 debuggable 的包)?
  • 检查 gradle task 的输出,是否有如上两个 task,例如 app:mergeReleaseArtProfile 和 :app:compileReleaseArtProfile。


这个地方需要注意,AGP 4.2.x 版本是支持正式版 Compose 的,但在看 4.2.x 版本源码的时候,是没有 ART Profiles 相关的 task 的,这也说明,在 AGP 4.2.x 生成不了 baseline.prof 文件,继而享受不到 Baseline Profile 带来的优化。


不过也有解决办法,那就是在高版本的 AGP 中打包,然后将 apk 里 assets 下的 baseline.prof 文件提取出来,放入到自己项目即可。


运行时


项目运行时,会通过 profileinstaller 模块将 assets/dexopt/baseline.prof 文件写入到 /data/misc/profiles/cur/0/包名/primary.prof 下,profileinstaller 模块在哪引入的呢?我们来打印下依赖树: 

profileinstaller 依赖被 compose.ui 模块给带进去了,并且 profileinstaller 还把 startup 库也给带进去了,来看下最终 apk 包的清单文件: 

应用启动时,通过 startup 库将 ProfileInstallerInitializer 启动起来,我们可以简单看下 ProfileInstallerInitializer 类: 

  • Android 7.0 以下不支持,直接返回不处理;

  • 为了避免因为写入 baseline.prof 影响到应用的启动,固注册在第一帧之后再延迟 5s 左右执行写入操作。


看下写入的操作: 

  • 判断是否强制写入或是已经写入过,强制写入默认是 false,如果已经写入则不处理;

  • transcodeAndWrite 在子线程中开始执行写入操作。


Profileinstaller 的源码非常简单,总共才 10 个类,但这里面需要注意一些细节: 
  • 在 transcodeAndWrite 方法内有判断 /data/misc/profiles/cur/0/包名路径是否可写,如果各厂商把这块设置成不可写的话,则无法写入;
  • profileinstaller 是在应用安装完成第一次启动的时候会做写入操作,在打开应用尚未写入完成时,这个时候是无法享受 AOT 带来的优化,所以,这次启动数据会有一定的劣化,不过,只有第一次安装打开时才会,尚可忽略。


衡量 Baseline Profiles 带来的提升



我们需要测量 Compose 项目有无 Baseline Profiles 加持时性能的对比,默认我们的 compose 项目就有了 Profiles 加持,我们需要移除 Profiles 能力来测试启动性能,有两种办法可以解决: 


从 baseline.prof 入手


我们只需要解决不将 baseline.prof 文件打入 apk 即可,或是说即使打入进去了,不将 profileinstaller 依赖打进 apk 也可以,这样的话,在运行期间就不会将 prof 文件写入到本地。最简单的方式就是 gradle.properties 中配置 ArtProfiles 为 false: 

android.enableArtProfiles=false

该值对应到上文编译章节开头描述的 variant.service.projectOptions[BooleanOption.ENABLE_ART_PROFILES] 判断,该值默认是个 true,我们设置 false 即可不启用 ArtProfile task,在产出包之后,通过 adb 命令即可获得启动数据: 


adb shell am start -W 包名/启动类

MacroBenchmark 测试


上面的测试可能会比较麻烦,可以利用 MacroBenchmark 来自动化测试有无 Baseline Profiles 加持的启动数据,单元测试如下: 

测量结果:

△ 测试 10 组数据,中位数的值比没有 Profiles 加持快 30ms 左右

这里就贴一个样本吧,因为在多次的测试过程中,大部分都是有 Profiles 加持的情况下比没有的快,但也遇到一次奇葩的时候: 

△ 测试 10 组数据,中位数的值比没有 Profiles 加持慢了 70ms 左右

这让我对 MacroBenchmark 保持了怀疑的态度,后面有时间,等我用 adb 的方式测一下吧。





长按右侧二维码

查看更多开发者精彩分享




"开发者说·DTalk" 面向中国开发者们征集 Google 移动应用 (apps & games) 相关的产品/技术内容。欢迎大家前来分享您对移动应用的行业洞察或见解、移动开发过程中的心得或新发现、以及应用出海的实战经验总结和相关产品的使用反馈等。我们由衷地希望可以给这些出众的中国开发者们提供更好展现自己、充分发挥自己特长的平台。我们将通过大家的技术内容着重选出优秀案例进行谷歌开发技术专家 (GDE) 的推荐。




 点击屏末 | 阅读原文 | 即刻报名参与 "开发者说·DTalk" 




相关阅读

  • 参与 2023 第一季度官方 Flutter 开发者调查

  • Flutter 3.7 已经正式发布,每个季度一次的 Flutter 开发者调查也如约而至,邀请社区的各位成员们填写!调查表链接:https://flutter.cn/urls/2023q1wx本次调研将会涉及既有的对 F
  • .8女神节 | 唯有美丽和健康无可替代

  • 温馨提示:距离女生节仅剩7天。女神节礼物的第二波真诚建议送上。对于女性而言,变美和健康是一生都在努力完成的功课。作为新时代的女性,一个人时尚风格的构建,除了依靠时髦单品
  • 基于ROS的机器人建图与导航仿真全过程

  • 点击下方卡片,关注“新机器视觉”公众号重磅干货,第一时间送达来源丨古月居引言之前一直想写一篇关于ROS机器人建图与导航仿真全过程的教程,终于有时间来做这个事啦,本人也拿过
  • 国家电投5.04MW/48.66MWh铅碳电池储能电站EPC招标

  • 文 | 中关村储能产业技术联盟国家电投煤山用户侧共享储能项目Ⅰ期工程EPC总承包招标公告云南鸿立招标代理有限公司受招标人委托,对国家电投煤山用户侧共享储能项目Ⅰ期工程EP
  • 首富新饼...

  • 今日份热点是马首富刚发布的宏图3计划,又给全世界画了一个大饼。大佬们的爱好就是画饼,区别就是能否实现。马斯克的瓜很多,但真正奠定江湖地位的还是前面两次画的饼基本都实现

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 苏州疾控提醒!三月份要注意!

  • 三月乍暖还寒气温多变,病原微生物活跃市民踏青出游增加呼吸道类和肠道类传染病发生和传播的可能性比较高苏州疾控提醒市民三月来临请特别关注以下疾病↓↓↓流行性感冒关注度
  • 不用再跑腿的电子版人事档案存放证明上线啦

  • “你好。请问一下,流动人员人事档案存放证明是到你们这里开具吗?我是黄浦户籍,但是住在宝山,怕跑错了地方,所以先来打电话咨询一下。”近日,黄浦区就业促进中心的工作人员接到了家
  • 【春风行动·招聘】上海地铁第一运营有限公司

  • 在沪企业如有招聘需求,可在“黄浦就业”平台上免费发布,具体发布要求可点击阅读原文查看。转载请注明来自“黄浦就业”官方微信扫码关注我们这里有招聘信息;职业、创业指导;就业