华为继去年推出黑科技 GPU Turbo 以后,今年再次扔出了一枚重磅炸弹, 安卓性能革命,华为方舟编译器
,号称解决安卓程序 “边解释边执行” 的低效,全程执行机器码高效运行程序。架构级优化,显著提高性能。系统操做流畅度提高 24%,系统响应提高 44%,三方应用操做流畅度提高 60%,并承诺向业界开源。勇于开源的话,这个数据应该没有水分。你们在网上应该也看到了 P30 Pro 吊打 S10 的视频。php
解决安卓程序 “边解释边执行” 的低效,什么是边解释边执行?也就是说,Android 是如何执行 Apk 中的代码的?这得从机器码提及。java
不管是低级语言,如汇编,仍是现在普遍使用的各类高级语言,Java,C++ 等,对于 CPU 来讲,所有都是天书。它能认识的只有二进制的机器码。固然,机器码对你来讲,也是天书。那你应该如何指挥 CPU 运行你的程序呢?这个时候,大家之间就须要一个翻译,将你的代码翻译成机器码给 CPU,它就知道该如何执行了。面对不一样的终端,翻译内容也不同,你一个只知道 x86 指令集的去翻译 arm 的,确定翻译不出来,就好似拿着本英语字典去翻译日语。翻译也有工具,下面说说几种常见的翻译工具:python
将汇编代码直接翻译成机器码。因为汇编代码通常和机器码都是一一对应的,因此它的速度很是快。只是汇编语言,你懂的,可读性差, 用起来难,用来写大型程序对于普通开发者基本是不现实的。缓存
编译器将咱们日常开发用的高级语言,例如 Java/C++ 等,翻译成机器码供 CPU 使用。这种编译很慢,可是执行起来会很快。微信
程序不须要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译一次。所以效率比较低。能够想象这种运行方式就慢了不少。 典型的解释型语言,php/js/python 等。架构
Java 程序的执行依赖于 Java 虚拟机(JVM),JVM 能直接识别的叫作字节码。Java 代码通过编译会生成 Class 文件,即字节码文件,再交由 JVM 处理。而 JVM 又是怎么执行 Class 文件的呢?这里以 HotSpot 为例,Class 文件被虚拟机加载后会存放在方法区,实际运行时,虚拟机会执行方法区中的代码。app
将字节码翻译成机器码的工做天然就由 JVM 来承担了。在 HotSpot 中,有几种翻译形式。函数
逐条将字节码翻译成机器码并执行工具
将一个方法中包含的全部字节码编译成机器码后再执行。性能
前者的优点在于无需等待编译,然后者的优点在于实际运行速度更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译两 者的优势。它会先解释执行字节码,然后将其中反复执行的热点代码,以方法为单位进行即时编译。
开发 Android 目前用的最多的仍是 Java,即便不是 Java,也是 JVM 语言。Android 工程中的 java 源文件通过编译也是生成 Class 文件,最后被打包成 DEX 字节码文件,负责将 DEX 字节码翻译成机器码的是 Dalvik 或者 Art。
在 Android 5.0 以前,仍是 Dalvik 的天下。Dalvik 是解释执行加上 JIT,每次app运行的时候,它动态的将一部分 Dalvik 字节码 解释为机器码。随着 App 的运行,更多的字节码被编译和缓存。由于 JIT 只编译了一部分代码,它具备更小的内存占用和更少的设备物理空间占用。可是,边解释边执行,效率低下,这也是后来 Dalvik 遭到抛弃的缘由。
从 Android 4.4 开始,Android 引入了 Art,到 Android 5.0,Art 正式代替了 Dalvik。Art 使用的是 AOT(Ahead of Time)的编译方式,即在应用的安装过程当中,就将全部的 Dex 字节码翻译成机器码存储在设备空间中,彻底抛弃了 JIT,带来的好处是显而易见的。
Apps 运行的更快,由于 DEX 字节码的解释在安装过程当中已经完成,直接运行机器码
减小了应用的启动时间,由于本地代码能够直接执行。
节省电量消耗,不须要再去一行一行的解释字节码。
加强了垃圾回收。
加强了开发者工具。
直接运行机器码
,恩,等等,这不就是方舟编译器作的事情吗?答案确定是否认的,不然它由于彻底没有存在的必要了。事实上,这种彻底基于 AOT 的模式也已经被 Android 抛弃了。若是你用过 5.0 或者 6.0 的安卓机,你必定不会忘记安装应用带来的漫长等待。因为须要在安装期间翻译字节码,因此安装过程会很长,尤为对 一些大型应用来讲。另外,安装过程当中翻译出来的机器码也占用了更大的机身存储空间。
Android 7.0,Android 又加入了 JIT,一个具有代码分析功能的即时 (JIT) 编译器。事实上,根据二八定律,常常运行的热点代码可能只占 20%,甚至更少,咱们没有必要经过 AOT 提早将全部字节码都翻译成机器码。安装过程当中放弃 AOT,加快安装速度,因此初次使用时得解释执行。当你在使用应用时,JIT 就开始分析代码了,在合适的时候将字节码翻译成机器码,在 Android 应用运行时持续提升其性能。另外,设备空闲的时候,AOT 就发挥做用了,它会将热点代码翻译成机器码并保存下来,进一步提升运行效率。这么看下来,如今的 Android 是 解释执行 、JIT、AOT 同时存在的。下面这张官网的图片很好的说明了Art 下的 JIT 架构.
关于解释器,高版本中的 Android 实现也再也不那么孱弱了,根据官网相关介绍:
经过引入 Mterp(一种解释器,具备以汇编语言编写的核心提取/解码/解释机制),Android 7.0 版本中的解释器性能得以显著提高。Mterp 模仿了快速 Dalvik 解释器,并支持 arm、arm6四、x8六、x86_6四、mips 和 mips64。对于计算代码而言,ART 的 Mterp 大体至关于 Dalvik 的快速解释器。 不过,有时候,它的速度可能会显著变慢,甚至急剧变慢:
- 调用性能。
- 字符串操做和 Dalvik 中其余被视为内嵌函数的高频用户方法。
- 堆栈内存使用量较高。
Android 8.0 解决了这些问题。
说了这么多,无非是安装速度,空间占用,运行速度的平衡,目前 Android 应该已经作得很好了,但仍然存在很多诟病。
如今能够肯定的是,方舟编译器绝对不多是 彻底 AOT。PPT 中最后一句话是 “但愿 APP 厂商尽快使用” ,并非手机厂商,因此不排除方舟编译器能够直接将 Apk ,或者说 Apk 中的 DEX 打包成机器码格式。但因为机器码并非平台兼容的,因此并不能肯定方舟编译器是否必需要绑定 EMUI。其实说到底,这一切都应该是为了华为的新手机系统做铺垫。华为的野心之大,以及其极其超前的技术储备,相信一个完整华为生态已经离咱们不远了。
编译器叫方舟,新系统干脆就叫 诺亚 吧!
文章首发于微信公众号:
秉心说
, 专一 Java 、 Android 原创知识分享,LeetCode 题解,欢迎扫码关注!