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) {
  let file = await fileOpen(path);
  try {
    while (!file.EOF) {
      yield await file.readLine();
    }
  } finally {
    await file.close();
  }
}

上面的 187 個字符會被 babel 編譯成 2987 個字符,代碼大小增加了 650%。文件地址:https://gist.github.com/justjavac/cdfe4cc0a55744e093250b8aca6a325a

對於數組和對象的析構賦值(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 引擎進展可以看看 V8 的 《ES2015 and beyond performance plan(需科學上網)》。

參考文章:

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

perfcomparison.png
justjavac V8
justjavac V8
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章