前段时间太极支持了 Android 14,不过有童鞋反馈,Android 12 还有 13 的设备一夜之间就出现了莫名其妙的闪退;经过一番调查,原因是 Google 通过主线更新的方式,把 Android 14 ART 上的改进,带入到了 Android 12 以上的设备上。据 Google 官方宣称,这一改进的性能提升是巨大的,竟然高达 30% 以上!
不过,主线更新是通过 Google Play 商店进行的;因此,除非你有办法把系统升级到 Android 14,国内低版本的系统是没办法享受这一更新的好处了。
好消息是,我在调查这一系列问题的过程中发现了太极的一个惊天大 Bug!修复这一 Bug 后,可以让太极内部的应用性能提升 200% 以上!对,你没看错,是 200%,不是 20%!简直吊打 Google 官方优化!是的,我只需要先负优化把性能拉低,然后随便搞搞就能让用户乐开花了... bushi
以下内容涉及专业知识,不感兴趣的可以略过直接跳到最后。
事情要从 Android 的解释器说起。在 Android 系统里,用 Java / Kotlin 写成的 App 的代码主要分为两种执行模式:解释器和机器码;其中机器码按照指令生成的时机,又分为提前编译(Ahead-of-Time, AOT)和及时编译(Just-in-Time, JIT);解释执行的模式性能很差,机器码的性能则很好,但不论是在安装的时候提前生成还是运行时及时生成机器码,这个过程都比较费时间以及消耗 CPU(耗电),之前鸿蒙的方舟编译器的牛逼之处在于它号称可以在打包的时候生成。
在 Android 上古时代(2.2 以下),只有解释器模式,因此 Android 系统性能非常差,简直可以用“卡得一比”来形容,于是 Google 引入了 JIT 编译器,一边运行解释器一边生成机器码,可惜效果还是不咋滴;然后有一位靓仔直接掀桌,表示 dalvik 是个垃圾我们要重写一个!于是 Android 4.4 引入了 ART(Android Runtime)并在 Android 5.0 转正成为 Android 系统默认的运行时,直至今天。
可能是 4.x 时代被解释器伤得太深,Android 5.0-6.0 默认全部采用 AOT 模式,也就是在应用安装的时候直接把所有代码编译成机器码;如果你还有印象的话,这个时候的 Android 系统安装应用灰常慢,更慢的是开机速度,直接半个小时起步,一个小时都不稀奇。
Android 7.0 吸取了这个教训,采用了混合编译的模式,刚安装的时候用解释器,运行过程中采用 JIT 收集信息,后台调用 dex2oat
进行 AOT,这个模式非常科学,一直沿用到现在;在这个大框架下,Google 一直在不遗余力地改进 ART 的性能,比如引进了 PGO(Profile guided optimization),也就是开发者提前收集编译信息,在 Google Play(对不起国内又用不了)分发的时候,直接把编译信息告诉用户设备,这样用户安装完就能直接调用机器码了;再比如 ART 会把 App 启动路径上的所有方法调用以及启动后五秒内执行的方法全部加入 JIT 而不管其执行热度... 总而言之,现在的 ART 在移动设备这个既要考虑功耗又对性能有要求的场景下,已经优化的很可以了。
ART 上虽然 AOT 和 JIT 的效率挺不错,但用户在初次安装并使用应用的时候,极大的可能是运行在解释模式下的,解释模式的性能其实非常影响用户体验!Google 显然不满足于此,一言不合,它又双叒叕重写了—— Android 11 引进了 nterp
解释器。这个 nterp
解释器有两个比较牛逼的地方:
1. 它完全是采用汇编实现的!光听这一点你就知道它很屌了。
2. 它的解释器栈帧结构跟机器码执行一样!也就是说,代码在机器码跟
nterp
解释器之间穿梭的时候,不需要维护单独的解释器栈帧,减少了亿点点上下文切换。
Android 11 的 nterp
解释器只支持 x86_64
,咱普通用户的手机基本上是 arm
的,因此还用不到;上面不是说嘛,这玩意全部用汇编实现的,写这玩意相当地费脑子(我打赌写 nterp
的那哥们头发不多了)。不过一年以后的 Android 12,nterp
正式支持了 arm
和 arm64
;今年发布的 Android 14,nterp
支持了 riscv64
(似乎是阿里云在玄铁处理器上实现的,终于进主线了,点赞!)
大家可能会好奇,这个 nterp
解释器吹的那么牛逼,真的很强吗?
我一开始也以为是“遥遥领先”,直到我触发了这个 Bug... 然后就被吓尿了。这个 Bug 的起因是,旧的 epic 采用 JIT 模式,当时的实现需要禁用 nterp
;去年我听 Google 吹牛说解释器性能爆炸,于是我把 epic 用解释器模式重写,然后忘记删掉禁用 nterp 这个逻辑 了;也就是,太极内部的应用,没法使用 nterp
解释器;结果导致 App 的启动性能下降了两倍以上。
在我重新启用 nterp
解释器以后,这是我当时的心情:
太流畅了卧槽,感觉像换了个新手机。我之前他妈的是吃屎去了吗,怎么忍得了的[破涕为笑]
用户也普遍表示,“流畅到飞起”,“秒进”,“卧槽真快!”。所以,还在等什么呢,赶紧去后台回复 最新版,升级太极吧!
补充两点:
1. Android 11 以及更低版本的系统不适用。
2. 基于第一点,鸿蒙 2.0 以及以下的系统不适用,鸿蒙 3.0/4.0 适用。
最后,大家晚安!
推荐阅读
欢迎关注我的公众号“虚拟框架”,原创技术文章第一时间推送。