成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

WebAssembly 系列(五)為什么 WebAssembly 更快?

劉德剛 / 2091人閱讀

摘要:圖表中的比例并不代表真實情況下的確切比例情況。解析當(dāng)?shù)竭_(dá)瀏覽器時,源代碼就被解析成了抽象語法樹。解析過后抽象語法樹就變成了中間代碼叫做字節(jié)碼,提供給引擎編譯。目前為止,不支持垃圾回收。這就是為什么在大多數(shù)情況下,同一個任務(wù)比表現(xiàn)更好的原因。

作者:Lin Clark

編譯:胡子大哈

翻譯原文:http://huziketang.com/blog/posts/detail?postId=58c8b98da6d8a07e449fdd25

英文原文:What makes WebAssembly fast?

轉(zhuǎn)載請注明出處,保留原文鏈接以及作者信息

本文作者:Lin Clark
英文原文:What makes WebAssembly fast?

本文是關(guān)于 WebAssembly 系列的第五篇文章(本系列共六篇文章)。如果你沒有讀先前文章的話,建議先讀這里。如果對 WebAssembly 沒概念,建議先讀這里(中文文章)。

上一篇文章中,我介紹了如何編寫 WebAssembly 程序,也表達(dá)了我希望看到更多的開發(fā)者在自己的工程中同時使用 WebAssembly 和 JavaScript 的期許。

開發(fā)者們不必糾結(jié)于到底選擇 WebAssembly 還是 JavaScript,已經(jīng)有了 JavaScript 工程的開發(fā)者們,希望能把部分 JavaScript 替換成 WebAssembly 來嘗試使用。

例如,正在開發(fā) React 程序的團(tuán)隊可以把調(diào)節(jié)器代碼(即虛擬 DOM)替換成 WebAssembly 的版本。而對于你的 web 應(yīng)用的用戶來說,他們就跟以前一樣使用,不會發(fā)生任何變化,同時他們還能享受到 WebAssembly 所帶來的好處——快。

而開發(fā)者們選擇替換為 WebAssembly 的原因正是因為 WebAssembly 比較快。那么為什么它執(zhí)行的快呢?我們來一起了解一下。

當(dāng)前的 JavaScript 性能如何?

在我們了解 JavaScript 和 WebAssembly 的性能區(qū)別之前,需要先理解 JS 引擎的工作原理。

下面這張圖片介紹了性能使用的大概分布情況。

JS 引擎在圖中各個部分所花的時間取決于頁面所用的 JavaScript 代碼。圖表中的比例并不代表真實情況下的確切比例情況。

圖中的每一個顏色條都代表了不同的任務(wù):

Parsing——表示把源代碼變成解釋器可以運(yùn)行的代碼所花的時間;

Compiling + optimizing——表示基線編譯器和優(yōu)化編譯器花的時間。一些優(yōu)化編譯器的工作并不在主線程運(yùn)行,不包含在這里。

Re-optimizing——當(dāng) JIT 發(fā)現(xiàn)優(yōu)化假設(shè)錯誤,丟棄優(yōu)化代碼所花的時間。包括重優(yōu)化的時間、拋棄并返回到基線編譯器的時間。

Execution——執(zhí)行代碼的時間

Garbage collection——垃圾回收,清理內(nèi)存的時間

這里注意:這些任務(wù)并不是離散執(zhí)行的,或者按固定順序依次執(zhí)行的。而是交叉執(zhí)行,比如正在進(jìn)行解析過程時,其他一些代碼正在運(yùn)行,而另一些正在編譯。

這樣的交叉執(zhí)行給早期 JavaScript 帶來了很大的效率提升,早期的 JavaScript 執(zhí)行類似于下圖,各個過程順序進(jìn)行:

早期時,JavaScript 只有解釋器,執(zhí)行起來非常慢。當(dāng)引入了 JIT 后,大大提升了執(zhí)行效率,縮短了執(zhí)行時間。

JIT 所付出的開銷是對代碼的監(jiān)視和編譯時間。JavaScript 開發(fā)者可以像以前那樣開發(fā) JavaScript 程序,而同樣的程序,解析和編譯的時間也大大縮短。這就使得開發(fā)者們更加傾向于開發(fā)更復(fù)雜的 JavaScript 應(yīng)用。

同時,這也說明了執(zhí)行效率上還有很大的提升空間。

WebAssembly 對比

下面是 WebAssembly 和典型的 web 應(yīng)用的近似對比圖:

各種瀏覽器處理上圖中不同的過程,有著細(xì)微的差別,我用 SpiderMonkey 作為模型來講解不同的階段:

文件獲取

這一步并沒有顯示在圖表中,但是這看似簡單地從服務(wù)器獲取文件這個步驟,卻會花費(fèi)很長時間。

WebAssembly 比 JavaScript 的壓縮率更高,所以文件獲取也更快。即便通過壓縮算法可以顯著地減小 JavaScript 的包大小,但是壓縮后的 WebAssembly 的二進(jìn)制代碼依然更小。

這就是說在服務(wù)器和客戶端之間傳輸文件更快,尤其在網(wǎng)絡(luò)不好的情況下。

解析

當(dāng)?shù)竭_(dá)瀏覽器時,JavaScript 源代碼就被解析成了抽象語法樹。

瀏覽器采用懶加載的方式進(jìn)行,只解析真正需要的部分,而對于瀏覽器暫時不需要的函數(shù)只保留它的樁。

解析過后 AST (抽象語法樹)就變成了中間代碼(叫做字節(jié)碼),提供給 JS 引擎編譯。

而 WebAssembly 則不需要這種轉(zhuǎn)換,因為它本身就是中間代碼。它要做的只是解碼并且檢查確認(rèn)代碼沒有錯誤就可以了。

編譯和優(yōu)化

上一篇關(guān)于 JIT 的文章中,我有介紹過,JavaScript 是在代碼的執(zhí)行階段編譯的。因為它是弱類型語言,當(dāng)變量類型發(fā)生變化時,同樣的代碼會被編譯成不同版本。

不同瀏覽器處理 WebAssembly 的編譯過程也不同,有些瀏覽器只對 WebAssembly 做基線編譯,而另一些瀏覽器用 JIT 來編譯。

不論哪種方式,WebAssembly 都更貼近機(jī)器碼,所以它更快,使它更快的原因有幾個:

在編譯優(yōu)化代碼之前,它不需要提前運(yùn)行代碼以知道變量都是什么類型。

編譯器不需要對同樣的代碼做不同版本的編譯。

很多優(yōu)化在 LLVM 階段就已經(jīng)做完了,所以在編譯和優(yōu)化的時候沒有太多的優(yōu)化需要做。

重優(yōu)化

有些情況下,JIT 會反復(fù)地進(jìn)行“拋棄優(yōu)化代碼<->重優(yōu)化”過程。

當(dāng) JIT 在優(yōu)化假設(shè)階段做的假設(shè),執(zhí)行階段發(fā)現(xiàn)是不正確的時候,就會發(fā)生這種情況。比如當(dāng)循環(huán)中發(fā)現(xiàn)本次循環(huán)所使用的變量類型和上次循環(huán)的類型不一樣,或者原型鏈中插入了新的函數(shù),都會使 JIT 拋棄已優(yōu)化的代碼。

反優(yōu)化過程有兩部分開銷。第一,需要花時間丟掉已優(yōu)化的代碼并且回到基線版本。第二,如果函數(shù)依舊頻繁被調(diào)用,JIT 可能會再次把它發(fā)送到優(yōu)化編譯器,又做一次優(yōu)化編譯,這是在做無用功。

在 WebAssembly 中,類型都是確定了的,所以 JIT 不需要根據(jù)變量的類型做優(yōu)化假設(shè)。也就是說 WebAssembly 沒有重優(yōu)化階段。

執(zhí)行

自己也可以寫出執(zhí)行效率很高的 JavaScript 代碼。你需要了解 JIT 的優(yōu)化機(jī)制,例如你要知道什么樣的代碼編譯器會對其進(jìn)行特殊處理(JIT 文章里面有提到過)。

然而大多數(shù)的開發(fā)者是不知道 JIT 內(nèi)部的實現(xiàn)機(jī)制的。即使開發(fā)者知道 JIT 的內(nèi)部機(jī)制,也很難寫出符合 JIT 標(biāo)準(zhǔn)的代碼,因為人們通常為了代碼可讀性更好而使用的編碼模式,恰恰不合適編譯器對代碼的優(yōu)化。

加之 JIT 會針對不同的瀏覽器做不同的優(yōu)化,所以對于一個瀏覽器優(yōu)化的比較好,很可能在另外一個瀏覽器上執(zhí)行效率就比較差。

正是因為這樣,執(zhí)行 WebAssembly 通常會比較快,很多 JIT 為 JavaScript 所做的優(yōu)化在 WebAssembly 并不需要。另外,WebAssembly 就是為了編譯器而設(shè)計的,開發(fā)人員不直接對其進(jìn)行編程,這樣就使得 WebAssembly 專注于提供更加理想的指令(執(zhí)行效率更高的指令)給機(jī)器就好了。

執(zhí)行效率方面,不同的代碼功能有不同的效果,一般來講執(zhí)行效率會提高 10% - 800%。

垃圾回收

JavaScript 中,開發(fā)者不需要手動清理內(nèi)存中不用的變量。JS 引擎會自動地做這件事情,這個過程叫做垃圾回收。

可是,當(dāng)你想要實現(xiàn)性能可控,垃圾回收可能就是個問題了。垃圾回收器會自動開始,這是不受你控制的,所以很有可能它會在一個不合適的時機(jī)啟動。目前的大多數(shù)瀏覽器已經(jīng)能給垃圾回收安排一個合理的啟動時間,不過這還是會增加代碼執(zhí)行的開銷。

目前為止,WebAssembly 不支持垃圾回收。內(nèi)存操作都是手動控制的(像 C、C++一樣)。這對于開發(fā)者來講確實增加了些開發(fā)成本,不過這也使代碼的執(zhí)行效率更高。

總結(jié)

WebAssembly 比 JavaScript 執(zhí)行更快是因為:

文件抓取階段,WebAssembly 比 JavaScript 抓取文件更快。即使 JavaScript 進(jìn)行了壓縮,WebAssembly 文件的體積也比 JavaScript 更小;

解析階段,WebAssembly 的解碼時間比 JavaScript 的解析時間更短;

編譯和優(yōu)化階段,WebAssembly 更具優(yōu)勢,因為 WebAssembly 的代碼更接近機(jī)器碼,而 JavaScript 要先通過服務(wù)器端進(jìn)行代碼優(yōu)化。

重優(yōu)化階段,WebAssembly 不會發(fā)生重優(yōu)化現(xiàn)象。而 JS 引擎的優(yōu)化假設(shè)則可能會發(fā)生“拋棄優(yōu)化代碼<->重優(yōu)化”現(xiàn)象。

執(zhí)行階段,WebAssembly 更快是因為開發(fā)人員不需要懂太多的編譯器技巧,而這在 JavaScript 中是需要的。WebAssembly 代碼也更適合生成機(jī)器執(zhí)行效率更高的指令。

垃圾回收階段,WebAssembly 垃圾回收都是手動控制的,效率比自動回收更高。

這就是為什么在大多數(shù)情況下,同一個任務(wù) WebAssembly 比 JavaScript 表現(xiàn)更好的原因。

但是,還有一些情況 WebAssembly 表現(xiàn)的會不如預(yù)期;同時 WebAssembly 的未來也會朝著使 WebAssembly 執(zhí)行效率更高的方向發(fā)展。這些我會在下一篇文章《WebAssembly 系列(六)WebAssembly 的現(xiàn)在與未來》中介紹。

我最近正在寫一本《React.js 小書》,對 React.js 感興趣的童鞋,歡迎指點(diǎn)。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/81996.html

相關(guān)文章

  • WebAssembly 系列(一)生動形象地介紹 WebAssembly

    摘要:但是為什么執(zhí)行的更快呢在這個系列文章中,我會為你解釋這一點(diǎn)。所以當(dāng)人們說更快的時候,一般來講是與相比而言的。被人們廣為傳播的性能大戰(zhàn)在年打響。性能的提升使得的應(yīng)用范圍得到很大的擴(kuò)展?,F(xiàn)在通過,我們很有可能正處于第二個拐點(diǎn)。 作者:Lin Clark 編譯:胡子大哈 翻譯原文:http://huziketang.com/blog/posts/detail?postId=58ce8036...

    wangbjun 評論0 收藏0
  • WebAssembly 什么比 asm.js 快?

    摘要:并且于年月日,四個主要的瀏覽器一致同意宣布的版本已經(jīng)完成,即將推出一個瀏覽器可以搭載的穩(wěn)定版本。因此本文著重介紹為什么比更快。本文主要表達(dá)的是為什么應(yīng)該是更快的。則不同,它是由幾大主要的瀏覽器廠商共同設(shè)計的。 作者:Alon Zakai 編譯:胡子大哈 翻譯原文:http://huziketang.com/blog/posts/detail?postId=58ce80d2a6d8a0...

    Binguner 評論0 收藏0
  • 圖說 WebAssembly):高性能原因

    摘要:本文是圖說系列文章的第五篇。這樣的話,使用的開發(fā)者也不需要做任何適配,但是它們卻能獲得更高性能。該圖并不是用來準(zhǔn)確的衡量其性能的。運(yùn)行編寫出高性能的代碼是可能的。這種清理工作由引擎自動進(jìn)行,稱為垃圾回收。 本文是圖說 WebAssembly 系列文章的第五篇。如果您還未閱讀之前的文章,建議您從第一篇入手。 在上一篇文章中,我們說到了使用 WebAssembly 和 JavaScript...

    seal_de 評論0 收藏0
  • WebAssembly 系列(六)WebAssembly 的現(xiàn)在與未來

    摘要:目前正在開發(fā)兩個編譯器系統(tǒng)。這就意味著有很多功能還在襁褓之中,沒有經(jīng)過徹底思考以及實際驗證。這些特性叫做未來特性。實現(xiàn)這一功能將會使用中的,而這一功能的實現(xiàn)將會提高程序執(zhí)行的效率。目前瀏覽器在逐漸支持用標(biāo)記來加載模塊。 作者:Lin Clark 編譯:胡子大哈 翻譯原文:http://huziketang.com/blog/posts/detail?postId=58ce7fd3a6...

    mcterry 評論0 收藏0
  • WebAssembly 系列(四)WebAssembly 工作原理

    摘要:但是它們其實并不是二選一的關(guān)系并不是只能用或者。正因為如此,指令有時也被稱為虛擬指令。這是因為是采用基于棧的虛擬機(jī)的機(jī)制。聲明模塊的全局變量。。下文預(yù)告現(xiàn)在你已經(jīng)了解了模塊的工作原理,下面將會介紹為什么運(yùn)行的更快。 作者:Lin Clark 編譯:胡子大哈 翻譯原文:http://huziketang.com/blog/posts/detail?postId=58c77641a6d8...

    stormzhang 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<