V8 效能再升級,支援更多 ES2015 語法優化

justjavac發表於2017-02-28

這幾天 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 效能再升級,支援更多 ES2015 語法優化

很早之前 V8 就已經更換了新的優化執行引擎:TurboFan,不僅僅可以優化 try/catch/finally、for...of 等之前 Crankshaft 不能優化的語法,還支援了更多的 ES2015+ features。

TurboFan 引擎不僅僅是增加了對 async 的支援,更增加了對 async、generators 優化的支援。下面是生成的二進位制碼和 TurboFan 執行圖:

V8 效能再升級,支援更多 ES2015 語法優化

在此之前很多需要藉助 babel 編譯的 ES2015 新特性都得到了原生支援。

非同步函式:

async function* readLines(path) {
  let file = await fileOpen(path);
  try {
    while (!file.EOF) {
      yield await file.readLine();
    }
  } finally {
    await file.close();
  }
}複製程式碼

上面的 187 個字元會被 babel 編譯成 2987 個字元,程式碼大小增加了 650%。檔案地址:gist.github.com/justjavac/c…

對於陣列和物件的析構賦值(array destructuring)

function fn() {
  var [c] = data;
  return c;
}複製程式碼

bable 編譯成:

"use strict";

var _slicedToArray = function () {...(此處省略630個字元)

function fn() {
  var _data = data,
      _data2 = _slicedToArray(_data, 1),
      c = _data2[0];
  return c;
}複製程式碼

檢視完整程式碼會發現裡面有 Crankshaft 無法優化的 try/catch/finally。而在最新 V8 裡面,析構賦值幾乎和陣列元素直接賦值一樣快:

function fn() {
  var c = data[0];
  return c;
}複製程式碼

其它的 ES2015+ 特性也有大幅度優化:

V8 效能再升級,支援更多 ES2015 語法優化

關注最新的 V8 引擎進展可以看看 V8 的 《ES2015 and beyond performance plan(需科學上網)》。

參考文章:

最後是廣告時間,歡迎訂閱我的公眾號:

V8 效能再升級,支援更多 ES2015 語法優化
justjavac V8

相關文章