V8 性能再升級,支持更多 ES2015+ 語法優化
這一切的功勞還要歸功於 V8 引擎。知乎上關於 async 的問題又重新出現在了 timeline 上:ES next中async/await proposal實現原理是什麼?我看到很多人在回答 async 本職是 promise、yield、generator,於是也湊熱鬧回答了一下,等晚上再看的時候,頓時有一種穿越感:
很早之前 V8 就已經更換了新的優化執行引擎:TurboFan,不僅僅可以優化 try/catch/finally、for...of 等之前 Crankshaft 不能優化的語法,還支持了更多的 ES2015+ features。TurboFan 引擎不僅僅是增加了對 async 的支持,更增加了對 async、generators 優化的支持。下面是生成的二進位碼和 TurboFan 執行圖:
在此之前很多需要藉助 babel 編譯的 ES2015+ 新特性都得到了原生支持。非同步函數:
async function* readLines(path) {n let file = await fileOpen(path);n try {n while (!file.EOF) {n yield await file.readLine();n }n } finally {n await file.close();n }n}n
上面的 187 個字元會被 babel 編譯成 2987 個字元,代碼大小增加了 650%。文件地址:https://gist.github.com/justjavac/cdfe4cc0a55744e093250b8aca6a325a
對於數組和對象的析構賦值(array destructuring)
function fn() {n var [c] = data;n return c;n}n
bable 編譯成:
"use strict";nnvar _slicedToArray = function () {...(此處省略630個字元)nnfunction fn() {n var _data = data,n _data2 = _slicedToArray(_data, 1),n c = _data2[0];n return c;n}n
查看完整代碼會發現裡面有 Crankshaft 無法優化的 try/catch/finally。而在最新 V8 裡面,析構賦值幾乎和數組元素直接賦值一樣快:
function fn() {n var c = data[0];n return c;n}n
其它的 ES2015+ 特性也有大幅度優化:
關注最新的 V8 引擎進展可以看看 V8 的 《ES2015 and beyond performance plan(需科學上網)》。
參考文章:
- High-performance ES2015 and beyond
- Async Iterators for JavaScript
- V8』s new interpreter and compiler pipeline
- V8s ES2015 and beyond performance plan
最後是廣告時間,歡迎訂閱我的公眾號:
推薦閱讀:
※chrome瀏覽器頁面渲染工作原理淺析
※超大文件如何計算md5?
※Chrome DevTools: 在 Profile 性能分析中顯示原生 JS 函數
※Runtime, Engine, VM 的區別是什麼?
※在不使用node的情況下,開發者怎樣在js里調用一個自己實現的c/c++函數?