箭头函数是否像命名函数一样进行了优化

Are arrow functions optimized like named functions?

本文关键字:函数 一样 优化 是否      更新时间:2023-09-26

我在看NodeJS Interactive的一个演讲,演讲的人说匿名函数有多糟糕,其中一个原因是如果它们没有名字,虚拟机就无法根据它的使用频率来优化函数,因为它没有名字。

因此,如果一个有名字的函数被称为

random.Async('Blah', function randomFunc() {});

randomFunc可以优化为其中的函数,如:

random.Async('Blah', function(cb) {});

这将不会被优化,因为它是匿名的。

所以我想知道箭头函数是否也能做同样的事情,因为我认为你不能命名箭头函数。

random.Async('Blah', (cb) => {});是否优化?

编辑:寻找链接的谈话,其中的家伙提到这一点,将报告回来。(这是一段时间前的演讲,只是我从中记得的东西)

编辑找到视频:https://youtu.be/_0W_822Dijg?t=299

注意,不完全确定这些是链接视频演示中讨论的模式比较。

在10000次迭代中,命名函数似乎在chrome的V8实现中完成得最快。Arrow function似乎比匿名函数在更短的时间内返回结果。

在100000次迭代中,匿名函数在最短的时间内完成;64.51ms比命名函数少,而箭头函数比命名函数花费4902.01ms更多的时间来完成。

    var len = Array.from({
      length: 100000
    })
     // named function
    function _named() {
      console.profile("named function");
      console.time("named function");
      function resolver(resolve, reject) {
        resolve("named function")
      }
      function done(data) {
        console.log(data)
      }
      function complete() {
        console.timeEnd("named function");
        console.profileEnd();
        return "named function complete"
      }
      function callback() {
        return new Promise(resolver).then(done)
      }
      return Promise.all(len.map(callback)).then(complete);
    }
     // anonymous function
    function _anonymous() {
      console.profile("anonymous function");
      console.time("anonymous function");
      return Promise.all(len.map(function() {
          return new Promise(function(resolve, reject) {
              resolve("anonymous function")
            })
            .then(function(data) {
              console.log(data)
            })
        }))
        .then(function() {
          console.timeEnd("anonymous function");
          console.profileEnd();
          return "anonymous function complete"
        })
    }
     // arrow function
    function _arrow() {
      console.profile("arrow function");
      console.time("arrow function");
      return Promise.all(len.map(() => {
          return new Promise((resolve, reject) =>
              resolve("arrow function")
            )
            .then((data) => {
              console.log(data)
            })
        }))
        .then(() => {
          console.timeEnd("arrow function");
          console.profileEnd();
          return "arrow function complete"
        })
    }
    _named().then(_anonymous).then(_arrow)

jsfiddlehttps://jsfiddle.net/oj87s38t/

我相信Matteo所指的是调用次数很少的函数(例如,只调用一次的回调),v8优化与该函数是否真正匿名无关。

此外,如果你继续观看,他提到使用一个名为reusify的模块,该模块基本上提供了一个函数池。通过使用它,意味着您可以从可能已经优化的池中获得一个函数,这意味着它可以执行得比典型的一次性回调更快。然而,并不是所有的用例都能够使用这样的东西。