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