華爲繼去年推出黑科技 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 題解,歡迎掃碼關注!