javascript - 为什么 `void 0` 可能是 “faster” 而不是 `undefined` ?

标签 javascript performance

只是潜伏在 140byte docs 的奇怪而奇特的东西上并发现this :

void 0 is faster than undefined but longer than the alternatives.

我在 Chrome 控制台中懒惰地检查了一下,如下所示:

console.time('void');
for (let a = 0; a < 1e6; a++) {() => void 0};
console.timeEnd('void');

对比

console.time('undefined');
for (let a = 0; a < 1e6; a++) {() => undefined};
console.timeEnd('undefined');

并没有发现任何差异。也许我的惰性检查太懒了,或者只是关于缓慢的陈述不再相关了。

我只是想知道 JS 引擎的内部结构以及它是如何实现的?我们如何谈论原语和运算符的速度?它是否正确且相关?我觉得这听起来有点奇怪。

最佳答案

I’m just wondering about the JS engines internals and how it could be possible? How can we talk about the speed of primitives and operators? Is it correct and relevant? It sounds a little bit odd to me.

是的,这是可能的。 undefined 是一个全局变量,而不是关键字。这意味着它可以被遮蔽。因此,为了找到它的值,JavaScript 引擎需要遍历作用域链并检查每个作用域级别的 "undefined" 绑定(bind)。例如:

function outer() {
    function middle() {
        function inner() {
            console.log(undefined);
        }
        inner();
    }
    middle();
}
outer();

inner 内部的引用要求 JavaScript 引擎检查 inner 函数的执行上下文的绑定(bind)对象,然后检查 middle 的绑定(bind)对象,然后 outer's,最后在全局级别找到它。 (当然,如果合理的话,JavaScript 引擎可以对其进行优化。)

相反,voidvoid运算符的关键字,而0是文字,因此void 0 不需要遍历作用域链。由于 void 运算符被定义为始终返回 undefined,因此有一种机制可以使其比 undefined 执行得更好全局。

这可能并不重要。您更有可能做其他事情来影响您的表现。

FWIW,一个幼稚的基准:

var x = undefined;

var now = performance && performance.now ? performance.now.bind(performance) : Date.now.bind(Date);

function outermost() {
  var a = Math.random();
  function outer() {
    var b = Math.random();
    function inner() {
      var c = Math.random();
      function test1() {
        if (Math.random() > 1) { // Never true
          x = 42;
        }
        return x == undefined;
      }

      function test2() {
        if (Math.random() > 1) { // Never true
          x = 42;
        }
        return x == void 0;
      }

      function test(f, n) {
        var start = now();
        while (n-- > 0) {
          f();
        }
        return now() - start;
      }

      console.log("Testing...");
      setTimeout(function() {
        test(test1, 100000000); // warmup
        test(test2, 100000000); // warmup
        console.log("undefined", test(test1, 1000000000), "ms");
        console.log("void 0   ", test(test2, 1000000000), "ms");
      }, 40);

      if (a + b + c > Infinity) {
        console.log("Impossible, just making sure to use a, b, and c");
      }
    }
    inner();
  }
  outer();
}
outermost();
WARNING: THIS MAY LOCK UP YOUR BROWSER WINDOW.
For me, it runs fine on recent Chrome, taking about 20 seconds; YMMV.

关于javascript - 为什么 `void 0` 可能是 “faster” 而不是 `undefined` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40358520/

相关文章:

performance - 最差抽象反转

javascript - XUL JS 打印错误到控制台

javascript - 在路径中绘制 svg 标记

javascript - Immutable.js 中的 GroupBy,然后返回分组列表的第一个值

javascript - 如何在 Firebase 中写入非规范化数据

javascript - 传单如何通过坐标添加圆圈?

performance - 为什么添加多态类型签名会降低性能?

performance - 涉及英特尔SnB系列CPU上涉及微编码指令的循环的分支对齐

java - 频繁 Integer.toString() 转换的内存问题

Python优化如何在列表中查找重复值和值索引