目前,關於華為鴻蒙操作系統網絡上議論紛紛,本文將從計算機編譯角度對鴻蒙操作系統可能的性能做一些通俗的解釋。

1.代碼編譯

1.1編譯流程

大家都知道,計算機最終執行的代碼都是“10101010”二進制的,而程序員所寫的代碼都是“源代碼”,所以,為了讓“源代碼”變成“可執行的程序”,計算機提供了“編譯”功能。通俗的說,就是把“源代碼”轉換為二進制的“1010”。這種編譯並不僅僅是“翻譯”這麼簡單,還有複雜的邏輯檢驗、錯誤提示,代碼合併等等。

在實際軟件開發中,軟件通常會比較大,例如chrome瀏覽器,大約有4000萬行代碼,這個代碼不會是在一個文件裡,而是分成不同的項目,最後,再把所有項目整合起來,形成一個最終的exe。

下圖顯示的普通程序編程流程圖。展示2個開發人員分別寫了2個程序c++程序,姑且叫做a.cpp和b.cpp,通過編譯為a.obj和b.obj,再通過鏈接生成了 main.exe

華為鴻蒙操作系統會不會比谷歌的Android更快?

1.2 什麼叫編輯

編輯(edit)代碼即編寫代碼,是編程的第一步。你可以任意一個編輯器進行代碼的編寫。你可以使用 Windows 自帶的“記事本”來編寫代碼,也可以使用Notepad++,或者 Visual Studio,Eclipse等 提供的編輯器。

華為鴻蒙操作系統會不會比谷歌的Android更快?

使用記事本寫代碼

雖然可以使用記事本軟件編輯代碼,但是記事本軟件的功能非常有限。缺少常用的語法高亮,自動縮進等功能。所以可以使用其他功能更豐富的編輯器,如Notepad++等。

華為鴻蒙操作系統會不會比谷歌的Android更快?

千萬不要小看編輯器,例如微軟之所以能讓成千上萬的程序員在windows寫程序,就是因為有號稱宇宙第一的編輯器-Visual Studio

1.2 什麼叫編譯

編譯(compile)是將用某種編程語言(如上面的C++語言)寫成的源代碼,轉換成目標文件。目標文件包含著機器代碼可直接被計算機中央處理器CPU執行,請注意這句話,後面我們會詳細討論它)以及代碼在運行時使用的數據。編譯器(compiler)是實現這一目的的軟件。編譯器有很多,如在 Windows 下有微軟公司的 cl.exe,在 Linux 下有 gcc 和 g++。在命令行下使用 cl.exe 對 hello.cpp 源代碼進行編譯,如下圖顯示的代碼編譯後,生成了目標文件hello.obj

華為鴻蒙操作系統會不會比谷歌的Android更快?

1.3什麼叫鏈接?

連接(link)是將多個目標文件,以及庫文件生成可執行的文件(或靜態庫、或動態庫)的過程。連接器(linker)是實現這一目的的軟件。常用的連接器有Windows 下的 link.exe,Linux 下的 ld 等。在 Windows 下可以使用 link.exe 將前面生成的 hello.obj 連接為可執行文件--最終生成了hello.exe

華為鴻蒙操作系統會不會比谷歌的Android更快?

1.4 什麼叫運行

運行(run)較容易理解,我們在 Windows 資源管理器裡用鼠標雙擊 exe 可執行程序,可以使程序被載入 CPU 運行。我們也可以在命令行窗口中輸入可執行程序的文件名運行,如下圖。

華為鴻蒙操作系統會不會比谷歌的Android更快?

通過上面1-4步驟的介紹,最終您編寫的源代碼變成了CPU可以直接執行的1010二進制代碼。現在,你大致瞭解了程序是怎麼開發的。

2.Java虛擬機

傳統軟件人員在使用C/C++編寫程序時,是需要考慮到硬件特徵的,這是因為不同的操作系統對代碼的定義並不相同。例如一個整數(以下假設僅供說明):如果8位的windows提供的最大整數是:

int max =2^7=128(假設操作系統佔用了1位)

而8位Linux提供的最大整數是

int max=2^8=256.(假設操作系統不佔用位數)

這種代碼的差異,使得程序員在編寫程序時,需要對硬件和操作系統平臺有深刻的認識,阻礙了軟件業的發展。

在這個時候Java誕生了。Java給出了自己的解決方案:Java虛擬機。

Java虛擬機是在源代碼和CPU之間,建立一個“虛擬的層”。程序員在寫代碼時,使用Java提供的“虛擬代碼”(注意:這裡僅是舉例,方便理解。)

 int max= int.MaxValue

是的,源代碼裡定義的變量並不是寫死的,後期,windows和Linux分別安裝Java虛擬機,由虛擬機來最終生成你定義的數據。

當程序員編寫的代碼需要運行時,就分兩步:

第一步:Java虛擬機加載程序員編譯後的代碼

第二部:CPU加載Java虛擬機代碼

通過這種“兩步加載”的方式,實現了程序員編寫一個程序,可以在不同的操作系統上運行。因為有Java虛擬機來幫助你做“底層”的映射。

如果總結一下就是:

程序員編寫代碼的流程是:源代碼-Java虛擬機-CPU,
而執行順序正好相反:CPU-加載Java虛擬機-加載程序

3.JIT和AOT

在上一步可以看到CPU無法直接加載Java源代碼,這導致了“安卓程序”總是不如“蘋果程序”流暢。因此,如果能把Java直接語言翻譯成 CPU 能理解的機器語言就好了。這時,出現了.JIT和AOT。

 (1) 在程序運行起來之後,實時地把 Java 語言編譯為機器語言然後執行。這種模式稱之為 JIT(Just in time) 編譯。
(2)在程序運行之前直接把 Java 代碼編譯為機器語言。這種模式我們稱之為 AOT (Ahead of time)編譯。

在 Android 5.0 正式採用 ART 之前,Android 採用的是 解釋執行 + JIT 的方式執行 Java代碼。在這個階段是貨真價實的「邊解釋邊執行」的模式,代碼效率相當低下,再加上那時候同樣差的 GC (垃圾回收),Android 用起來真是慘不忍睹。

Android 5.0 ~ Android 6.0 。Google 推出了 ART (Android Runtime)來解決之前的 Java 代碼執行效率問題。這個階段採用的是完全 AOT 模式;Android 應用在安裝的時候,系統會把所有Java代碼提前編譯為機器碼。這種模式有兩個缺點不能忍:

1.安裝速度巨慢。即使是現在吊炸天的 855 採用 AOT 模式編譯一下安裝包比較大的應用(如支付寶)可能就要一分鐘。那個時候的 CPU 可不如現在,安裝一個應用都讓你等得頭皮發麻。更要命的時候,系統 OTA 開機會對所有的應用執行 AOT 操作,這時候你的開機速度可能要半個小時。。。
2.佔用磁盤空間,Java 代碼編譯為機器碼之後體積會急劇膨脹。

Android 7.0 ~ 現在。Google做了很大的改進,基於這樣一個事實:我們使用一個應用的時候,基本每個人只使用它一小部分功能,為什麼要把所有代碼全編譯呢?只編譯你經常用的那部分代碼不就 OK 了,這樣安裝的時候啥也不幹速度飛快,等你用的時候系統就能知道哪部分代碼經常被執行,把這部分代碼編譯為機器碼,運行起來速度也快。於是 Google 又引入了 JIT,這時候的執行模式是 AOT + JIT + 解釋執行。應用安裝的時候不執行 AOT 編譯,安裝速度飛快。初次使用應用的時候沒有機器碼,因此只能解釋執行。

應用運行起來之後,系統收集經常被運行的代碼的信息,做兩件事:1)在必要的時候在運行時直接把 Java 代碼編譯為機器碼 (JIT),然後使用機器碼執行提高運行效率。2)把這個「經常被運行的代碼信息保存起來」設備空閒的時候,系統拿出應用運行時候保存的「熱點代碼信息」直接把這些代碼編譯為機器碼 (AOT)

Android 8.0上改進了解釋器,解釋模式執行效率大幅提升;Android 10.0上提供了預先放置熱點代碼的方式,應用在安裝的時候就能知道常用代碼會被提前編譯。可以看到,當前 Android 平臺的執行模式在空間佔用+安裝速度+運行速度上已經達到了一個很好的平衡。

4.方舟編譯器

華為早前宣佈退出自己的編譯器--方舟編譯器。號稱能讓APP的運行性能大幅度提醒。因為方舟編譯器還沒有公開,所以,這裡可以對方舟編譯器進行一些猜測。

但是在猜測前,還是找到問題的根源,和華為可能應對的解決方法:

Java因為需要跨平臺,所以,不得不提供一個“虛擬機”,讓程序“一次編譯,到處運行。”

因為虛擬機的存在,導致安卓App總慢人一籌

這是一個矛盾的存在,那麼華為既然用自己的操作系統+自己的芯片,那就學習蘋果,讓Java源代碼直接編譯為CPU可以識別的二進制。

這個和谷歌提供的AOT是不一樣的,因為谷歌提供的AOT是應用程序這個級別的,而如果華為的方舟編譯是讓源代碼直接編譯為二進制的機器名,這將達到操作系統級別的性能。

如果是這樣,可以說鴻蒙運行App的速度肯定會比android快很多。

華為鴻蒙操作系統會不會比谷歌的Android更快?

相關推薦

推薦中...