IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    V8 性能再升级,支持更多 ES2015 语法优化

    justjavac发表于 2017-02-28 08:48:28
    love 0

    这几天 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,于是也凑热闹回答了一下,等晚上再看的时候,顿时有一种穿越感:

    alt

    很早之前 V8 就已经更换了新的优化执行引擎:TurboFan,不仅仅可以优化 try/catch/finally、for…of 等之前 Crankshaft 不能优化的语法,还支持了更多的 ES2015+ features。

    TurboFan 引擎不仅仅是增加了对 async 的支持,更增加了对 async、generators 优化的支持。下面是生成的二进制码和 TurboFan 执行图:

    alt

    在此之前很多需要借助 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+ 特性也有大幅度优化:

    alt

    关注最新的 V8 引擎进展可以看看 V8 的 《ES2015 and beyond performance plan(需科学上网)》。

    参考文章:

    • High-performance ES2015 and beyond
    • Async Iterators for JavaScript
    • V8’s new interpreter and compiler pipeline
    • ES2015 and beyond performance plan

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

    justjavac V8



沪ICP备19023445号-2号
友情链接