西西軟件下載最安全的下載網(wǎng)站、值得信賴的軟件下載站!

首頁業(yè)內(nèi)動態(tài) 業(yè)內(nèi)資訊 → JS性能缺陷及JIT的解決方案 側(cè)面了解JIT

JS性能缺陷及JIT的解決方案 側(cè)面了解JIT

相關(guān)軟件相關(guān)文章發(fā)表評論 來源:西西整理時間:2013/2/6 20:29:06字體大。A-A+

作者:西西點擊:0次評論:0次標簽: JS JIT

3D性能測試 AllBenchmark1.0 Beta 19 官方版
  • 類型:系統(tǒng)優(yōu)化大小:500.9M語言:中文 評分:6.6
  • 標簽:
立即下載

拜讀了David的《Know Your Engines: How to Make Your JavaScript Fast》,David是Mozilla的JS引擎工程師,文章主要介紹了JIT與GC原理,以及如何根據(jù)某些基本原理,優(yōu)化js代碼的執(zhí)行效率,雖然是老文了,但對我來說仍受益匪淺。這里,我根據(jù)上文整理了本文,同時,大家也可以從側(cè)面了解下JIT。

近5年來,在主流瀏覽器上,Javascript的運行速度有10-100倍的提升,這要歸功于Javascript新引擎JIT。但在深入了解JIT前,我們先看看Javascript的一個最重要的特性:untyped(無類型)。

一. 無類型:

Javascript是個無類型的語言,這導致了 x = y +z這種表達式,可以有很多含義。比如:

(1)y,z是數(shù)字,則+表示加法。

(2)y,z是字符串,則+表示字符串連接。

 ……

而JS引擎內(nèi)部則使用“細粒度”的類型,比如:32-bit* integer, 64-bit* floating-point,如圖:

       

這就要求js類型-js引擎類型,需要做“boxed/unboxed(裝箱/解箱)”,在處理一次x = y + z這種計算,需要經(jīng)過的步驟如下:

(1)從內(nèi)存,讀取 x = y + z的操作符。

(2)從內(nèi)存,讀取 y,z。

(3)檢查y,z類型,確定操作的行為。

(4)unbox y,z。

(5)執(zhí)行 操作符 的行為(唯一有效的步驟……)。

(6)box x。

(7)把x寫入內(nèi)存。

只有(5)是真正有效的操作,其他都是為(5)做準備/收尾的,效率之低可見。javascript的untyped特性很好用,但也為此付出了很大的性能代價。

二. 對象屬性

function f(obj) {
        return obj.a + 1;
}
在Js里,對象屬性的訪問是比較慢的。至于原因,要從Javascript對象存儲說起,這里借用其他文章的一個圖:

       

 如上圖,訪問對象屬性,需要先從本地變量表找到對象,然后遍歷屬性,如果在本對象的屬性列表里沒找到,再得從prototype里面一層層的找。不能直接索引,只能遍歷,這就慢的原因。

二. 2006版-Javascript引擎

 這版引擎在執(zhí)行x = y + z時,就是執(zhí)行了以上流程。它模塊圖如下:

       

三. 2011新版-Javascript引擎

模塊圖如下:

       

 可以看到,除了老版的解析器外,新引擎增加了JIT,以及Type-specializing JIT。

1. JIT

先看看JIT對untyped的優(yōu)化,在JIT下,執(zhí)行x = y + z流程:

(1)從內(nèi)存,讀取 x = y + z的操作符。

(2)從內(nèi)存,讀取 y,z。

(3)檢查y,z類型,確定操作的行為。

(4)unbox y,z。

(5)執(zhí)行 操作符 的行為(唯一有效的步驟……)。

 (6)box x。

 (7)把x寫入內(nèi)存。

 其中,(1),(2) CPU幫我們搞定;(7)JIT把結(jié)果保存在寄存器里。

 但可惜不是所有情況都能使用JIT,上面看到,F(xiàn)ront-end有3條分支,“一般的情況”可以走JIT分支,比如:number + number;string + string …,但特殊情況,比如:number + undefined就不行了,只能走舊解析器。

 除了針對untyped的優(yōu)化,新引擎還對“對象屬性”訪問做了優(yōu)化,解決方案叫:inline caching,俗稱:IC。簡單的說,就是做cache。優(yōu)化流程直接看圖:

       

這個相當于遍歷cache list了,如果當list很大時,這種方案反而影響效率。下圖是評測:

       

2. Type-specializing JIT

從名稱上可以猜到,這個引擎是處理typed類型(聲明類型)變量的。厄……但Javascript都是untype類型的……

Type-specializing JIT的解決方案是:

(1)先通過掃描,監(jiān)測類型。

 (2)通過編譯優(yōu)化(當然,他的優(yōu)化對象不僅僅只是“類型”,還包括對JS代碼的優(yōu)化,但類型優(yōu)化是核心的。),生成類型變量。

 (3)再做后續(xù)計算。

來看看Type-specializing JIT的執(zhí)行x = y + z流程吧:

(1)從內(nèi)存,讀取 x = y + z的操作符。

(2)從內(nèi)存,讀取 y,z。

(3)檢查y,z類型,確定操作的行為。

(4)unbox y,z。

(5)執(zhí)行 操作符 的行為。

(6)box x。

(7)把x寫入內(nèi)存。

高效的優(yōu)化啊……當然,這也是有代價的,代價就是:前置的掃描類型,編譯優(yōu)化。所以Type-specializing JIT的應(yīng)用是有選擇性,選擇使用這個引擎的場景包括:

(1)熱點代碼。

(2)通過啟發(fā)式算法估算出來的有價值的代碼……

另外,有2點也需要注意:

(1)當 變量類型 發(fā)生變化時,引擎有2種處理方式:

【1】少量變更,重編譯,再執(zhí)行。

【2】大量變更……還是交給JIT執(zhí)行吧。

(2)數(shù)組,object properties,閉包變量不在優(yōu)化范疇之列。

    相關(guān)評論

    閱讀本文后您有什么感想? 已有人給出評價!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    發(fā)表評論 查看所有評論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字數(shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)