V8 性能再升級,支持更多 ES2015+ 語法優化

這幾天 javascript 最火的新聞莫過於 koa2 發布了正式版。目前最新版本是v2.0.1,koa2 團隊宣稱 「只要 nodejs 還未支持 async,koa2 就一直不發布正式版」,隨著 node v7.6.0 的到來,全棧工程師們期待已久的 koa2 也終於正式版了——完美支持 async 函數,優雅的解決非同步回調。

這一切的功勞還要歸功於 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%。文件地址:gist.github.com/justjav

對於數組和對象的析構賦值(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++函數?

TAG:V8 | ES2015 | 性能优化 |