華為繼去年推出黑科技 GPU Turbo 之后,今年再次扔出了一枚重磅炸彈, 安卓性能革命,華為方舟編譯器,號(hào)稱解決安卓程序 “邊解釋邊執(zhí)行” 的低效,全程執(zhí)行機(jī)器碼高效運(yùn)行程序。架構(gòu)級(jí)優(yōu)化,顯著提升性能。系統(tǒng)操作流暢度提升 24%,系統(tǒng)響應(yīng)提升 44%,三方應(yīng)用操作流暢度提升 60%,并承諾向業(yè)界開源。敢于開源的話,這個(gè)數(shù)據(jù)應(yīng)該沒有水分。大家在網(wǎng)上應(yīng)該也看到了 P30 Pro 吊打 S10 的視頻。
解決安卓程序 “邊解釋邊執(zhí)行” 的低效,什么是邊解釋邊執(zhí)行?也就是說,Android 是如何執(zhí)行 Apk 中的代碼的?這得從機(jī)器碼說起。
機(jī)器碼
不論是低級(jí)語(yǔ)言,如匯編,還是如今廣泛使用的各種高級(jí)語(yǔ)言,Java,C++ 等,對(duì)于 CPU 來說,全部都是天書。它能認(rèn)識(shí)的只有二進(jìn)制的機(jī)器碼。當(dāng)然,機(jī)器碼對(duì)你來說,也是天書。那你應(yīng)該如何指揮 CPU 運(yùn)行你的程序呢?這個(gè)時(shí)候,你們之間就需要一個(gè)翻譯,將你的代碼翻譯成機(jī)器碼給 CPU,它就知道該如何執(zhí)行了。面對(duì)不同的終端,翻譯內(nèi)容也不一樣,你一個(gè)只知道 x86 指令集的去翻譯 arm 的,肯定翻譯不出來,就好似拿著本英語(yǔ)字典去翻譯日語(yǔ)。翻譯也有工具,下面說說幾種常見的翻譯工具:
匯編器
將匯編代碼直接翻譯成機(jī)器碼。由于匯編代碼一般和機(jī)器碼都是一一對(duì)應(yīng)的,所以它的速度非??臁V皇菂R編語(yǔ)言,你懂的,可讀性差,
用起來難,用來寫大型程序?qū)τ谄胀ㄩ_發(fā)者基本是不現(xiàn)實(shí)的。
編譯器
編譯器將我們平常開發(fā)用的高級(jí)語(yǔ)言,例如 Java/C++ 等,翻譯成機(jī)器碼供 CPU 使用。這種編譯很慢,但是執(zhí)行起來會(huì)很快。
解釋器
程序不需要編譯,程序在運(yùn)行時(shí)才翻譯成機(jī)器語(yǔ)言,每執(zhí)行一次都要翻譯一次。因此效率比較低。可以想象這種運(yùn)行方式就慢了很多。
典型的解釋型語(yǔ)言,php/js/python 等。
JAVA 代碼是如何執(zhí)行的 ?
Java 程序的執(zhí)行依賴于 Java 虛擬機(jī)(JVM),JVM 能直接識(shí)別的叫做字節(jié)碼。Java 代碼經(jīng)過編譯會(huì)生成 Class 文件,即字節(jié)碼文件,再交由 JVM 處理。而 JVM 又是怎么執(zhí)行 Class 文件的呢?這里以
HotSpot 為例,Class 文件被虛擬機(jī)加載后會(huì)存放在方法區(qū),實(shí)際運(yùn)行時(shí),虛擬機(jī)會(huì)執(zhí)行方法區(qū)中的代碼。
將字節(jié)碼翻譯成機(jī)器碼的工作自然就由 JVM 來承擔(dān)了。在 HotSpot 中,有幾種翻譯形式。
- 解釋執(zhí)行
逐條將字節(jié)碼翻譯成機(jī)器碼并執(zhí)行
- 即時(shí)編譯(Just-in-time ,JIT)
將一個(gè)方法中包含的所有字節(jié)碼編譯成機(jī)器碼后再執(zhí)行。
前者的優(yōu)勢(shì)在于無需等待編譯,而后者的優(yōu)勢(shì)在于實(shí)際運(yùn)行速度更快。HotSpot 默認(rèn)采用混合模式,綜合了解釋執(zhí)行和即時(shí)編譯兩
者的優(yōu)點(diǎn)。它會(huì)先解釋執(zhí)行字節(jié)碼,而后將其中反復(fù)執(zhí)行的熱點(diǎn)代碼,以方法為單位進(jìn)行即時(shí)編譯。
Android 代碼是如何執(zhí)行的 ?
開發(fā) Android 目前用的最多的還是 Java,即使不是 Java,也是 JVM 語(yǔ)言。Android 工程中的 java 源文件經(jīng)過編譯也是生成
Class 文件,最后被打包成 DEX 字節(jié)碼文件,負(fù)責(zé)將 DEX 字節(jié)碼翻譯成機(jī)器碼的是 Dalvik 或者 Art。
在 Android 5.0 之前,還是 Dalvik 的天下。Dalvik 是解釋執(zhí)行加上 JIT,每次app運(yùn)行的時(shí)候,它動(dòng)態(tài)的將一部分 Dalvik 字節(jié)碼
解釋為機(jī)器碼。隨著 App 的運(yùn)行,更多的字節(jié)碼被編譯和緩存。因?yàn)?JIT 只編譯了一部分代碼,它具有更小的內(nèi)存占用和更少的設(shè)備物理空間占用。但是,邊解釋邊執(zhí)行,效率低下,這也是后來 Dalvik 遭到拋棄的原因。
從 Android 4.4 開始,Android 引入了 Art,到 Android 5.0,Art 正式代替了 Dalvik。Art 使用的是 AOT(Ahead of Time)的編譯方式,即在應(yīng)用的安裝過程中,就將所有的 Dex 字節(jié)碼翻譯成機(jī)器碼存儲(chǔ)在設(shè)備空間中,完全拋棄了 JIT,帶來的好處是顯而易見的。
Apps 運(yùn)行的更快,因?yàn)?DEX 字節(jié)碼的解釋在安裝過程中已經(jīng)完成,直接運(yùn)行機(jī)器碼
減少了應(yīng)用的啟動(dòng)時(shí)間,因?yàn)楸镜卮a可以直接執(zhí)行。
節(jié)省電量消耗,不需要再去一行一行的解釋字節(jié)碼。
增強(qiáng)了垃圾回收。
增強(qiáng)了開發(fā)者工具。
直接運(yùn)行機(jī)器碼,恩,等等,這不就是方舟編譯器做的事情嗎?答案肯定是否定的,否則它因?yàn)橥耆珱]有存在的必要了。事實(shí)上,這種完全基于 AOT 的模式也已經(jīng)被 Android 拋棄了。如果你用過 5.0 或者 6.0 的安卓機(jī),你一定不會(huì)忘記安裝應(yīng)用帶來的漫長(zhǎng)等待。由于需要在安裝期間翻譯字節(jié)碼,所以安裝過程會(huì)很長(zhǎng),尤其對(duì)
一些大型應(yīng)用來說。另外,安裝過程中翻譯出來的機(jī)器碼也占用了更大的機(jī)身存儲(chǔ)空間。
Android 7.0,Android 又加入了 JIT,一個(gè)具備代碼分析功能的即時(shí) (JIT) 編譯器。事實(shí)上,根據(jù)二八定律,經(jīng)常運(yùn)行的熱點(diǎn)代碼可能只占 20%,甚至更少,我們沒有必要通過 AOT 提前將所有字節(jié)碼都翻譯成機(jī)器碼。安裝過程中放棄 AOT,加快安裝速度,所以初次使用時(shí)得解釋執(zhí)行。當(dāng)你在使用應(yīng)用時(shí),JIT 就開始分析代碼了,在合適的時(shí)候?qū)⒆止?jié)碼翻譯成機(jī)器碼,在 Android 應(yīng)用運(yùn)行時(shí)持續(xù)提高其性能。另外,設(shè)備空閑的時(shí)候,AOT 就發(fā)揮作用了,它會(huì)將熱點(diǎn)代碼翻譯成機(jī)器碼并保存下來,進(jìn)一步提高運(yùn)行效率。這么看下來,現(xiàn)在的 Android 是 解釋執(zhí)行 、JIT、AOT 同時(shí)存在的。下面這張官網(wǎng)的圖片很好的說明了Art 下的 JIT 架構(gòu).
關(guān)于解釋器,高版本中的 Android 實(shí)現(xiàn)也不再那么孱弱了,根據(jù)官網(wǎng)相關(guān)介紹:
通過引入 Mterp(一種解釋器,具有以匯編語(yǔ)言編寫的核心提取/解碼/解釋機(jī)制),Android 7.0 版本中的解釋器性能得以顯著提升。Mterp 模仿了快速 Dalvik 解釋器,并支持 arm、arm64、x86、x86_64、mips 和 mips64。對(duì)于計(jì)算代碼而言,ART 的 Mterp 大致相當(dāng)于 Dalvik 的快速解釋器。
不過,有時(shí)候,它的速度可能會(huì)顯著變慢,甚至急劇變慢:
- 調(diào)用性能。
- 字符串操作和 Dalvik 中其他被視為內(nèi)嵌函數(shù)的高頻用戶方法。
- 堆棧內(nèi)存使用量較高。
Android 8.0 解決了這些問題。
說了這么多,無非是安裝速度,空間占用,運(yùn)行速度的平衡,目前 Android 應(yīng)該已經(jīng)做得很好了,但仍然存在不少詬病。
現(xiàn)在可以確定的是,方舟編譯器絕對(duì)不可能是 完全 AOT。PPT 中最后一句話是 “希望 APP 廠商盡快使用” ,并不是手機(jī)廠商,所以不排除方舟編譯器可以直接將 Apk ,或者說 Apk 中的 DEX 打包成機(jī)器碼格式。但由于機(jī)器碼并不是平臺(tái)兼容的,所以并不能確定方舟編譯器是否必須要綁定 EMUI。其實(shí)說到底,這一切都應(yīng)該是為了華為的新手機(jī)系統(tǒng)作鋪墊。華為的野心之大,以及其極其超前的技術(shù)儲(chǔ)備,相信一個(gè)完整華為生態(tài)已經(jīng)離我們不遠(yuǎn)了。
編譯器叫方舟,新系統(tǒng)干脆就叫 諾亞 吧!