說說 方舟編譯器

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

相關文章
相關標籤/搜索