V8 性能再升级,支持更多 ES2015+ 语法优化
发布于 4 个月前 作者 justjavac 592 次浏览 来自 分享

这几天 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(需科学上网)》。

参考文章:

最后是广告时间,欢迎订阅我的公众号:

justjavac V8

回到顶部