## `JIT`與`GC`優(yōu)化
> * `untyped`(無類型)。
>
>
> * `JAVASCRIPT`是個(gè)無類型的語言,這導(dǎo)致了如`x=y+z`這種表達(dá)式可以有很多含義。
>
>
> * `y`,`z`是數(shù)字,則`+`表示加法。
> * `y`,`z`是字符串,則`+`表示字符串連接。
>
> 而JS引擎內(nèi)部則使用“`細(xì)粒度`”的類型,比如:
>
>
> * 32-bit* integer。
> * 64-bit* floating-point。
>
> 這就要求js類型-js引擎類型,需要做“boxed/unboxed(裝箱/解箱)”,在處理一次`x=y+z`這種計(jì)算,需要經(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`步驟做準(zhǔn)備/收尾,`JAVASCRIPT`的`untyped`特性很好用,但也為此付出了很大的性能代價(jià)。
>
>
> * `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`負(fù)責(zé),`7`步驟`JIT`把結(jié)果保存在寄存器里。但可惜不是所有情況都能使用JIT,當(dāng)`number+number`,`string+string`?等等可以使用`JIT`,但特殊情況,如:`number+undefined`就不行了,只能走舊解析器。
>
>
> * 新引擎還對“對象屬性”訪問做了優(yōu)化,解決方案叫`inline caching`,簡稱:`IC`。簡單的說,就是做`cache`。但如果當(dāng)`list`很大時(shí),這種方案反而影響效率。
> * `Type-specializing JIT`
>
>
>
> > `Type-specializing JIT`引擎用來處理`typed`類型(聲明類型)變量,但`JAVASCRIPT`都是`untype`類型的。
>
>
> * `Type-specializing JIT`的解決方案是:
> * 先通過掃描,監(jiān)測類型。
> * 通過編譯優(yōu)化(優(yōu)化對象不僅僅只是“類型”,還包括對JS代碼的優(yōu)化,但核心是類型優(yōu)化),生成類型變量。
> * 再做后續(xù)計(jì)算。
> * `Type-specializing JIT`的執(zhí)行`x=y+z`流程:
>
>
> * 從內(nèi)存,讀取`x=y+z`的操作符。
> * 從內(nèi)存,讀取`y`,`z`。
> * 檢查`y`,`z`類型,確定操作的行為。
> * `unbox y,z`。
> * 執(zhí)行操作符的行為。
> * `box x`。
> * 把`x`寫入內(nèi)存。
>
> 代價(jià)是:
>
>
> * 前置的掃描類型
> * 編譯優(yōu)化。
>
> 所以·Type-specializing JIT·的應(yīng)用是有選擇性,選擇使用這個(gè)引擎的場景包括:
>
>
> * 熱點(diǎn)代碼。
> * 通過啟發(fā)式算法估算出來的有價(jià)值的代碼。
>
> 另外,有2點(diǎn)也需要注意:
>
>
> * 當(dāng)變量類型 發(fā)生變化時(shí),引擎有2種處理方式:
> * 少量變更,重編譯,再執(zhí)行。
> * 大量變更,交給JIT執(zhí)行。
> * `數(shù)組`,`object properties`, 閉包變量 不在優(yōu)化范疇之列。
