说说 方舟编译器

华为继去年推出黑科技 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 程序的执行依赖于 Java 虚拟机(JVM),JVM 能直接识别的叫作字节码。Java 代码通过编译会生成 Class 文件,即字节码文件,再交由 JVM 处理。而 JVM 又是怎么执行 Class 文件的呢?这里以 HotSpot 为例,Class 文件被虚拟机加载后会存放在方法区,实际运行时,虚拟机会执行方法区中的代码。app

将字节码翻译成机器码的工做天然就由 JVM 来承担了。在 HotSpot 中,有几种翻译形式。函数

  • 解释执行

逐条将字节码翻译成机器码并执行工具

  • 即时编译(Just-in-time ,JIT)

将一个方法中包含的全部字节码编译成机器码后再执行。性能

前者的优点在于无需等待编译,然后者的优点在于实际运行速度更快。HotSpot 默认采用混合模式,综合了解释执行和即时编译两 者的优势。它会先解释执行字节码,然后将其中反复执行的热点代码,以方法为单位进行即时编译。

Android 代码是如何执行的 ?

开发 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 题解,欢迎扫码关注!

相关文章
相关标签/搜索