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

这几天 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

回到顶部