简体   繁体   English

为什么检查void 0比检查undefined快得多?

[英]Why is checking void 0 so much faster than checking undefined?

I noticed something interesting after using gulp-uglify on my concatenated javascript. 在我的连接javascript上使用gulp-uglify之后我发现了一些有趣的东西。 I was passing in undefined to a global IIFE wrapper and I saw that it was changing it to void 0 . 我将undefined传递给全局IIFE包装器,我发现它将它更改为void 0 What the heck is void 0? 什么是无效0? I ran it in the console and it returned undefined. 我在控制台中运行它并返回undefined。 Interesting! 有趣! This got me curious, so I started running tests on void 0. In my console tests (simple loops and timestamps), I have observed as much as a 180x speed increase, depending on browser, checking void 0 instead of undefined . 这让我很好奇,所以我开始在void 0上运行测试。在我的控制台测试(简单循环和时间戳)中,我观察到的速度提高了180倍,具体取决于浏览器,检查void 0而不是undefined Does anyone know why checking void 0 is so much faster? 有谁知道为什么检查void 0是如此之快?

(function(start, x, z){
    for (var i=0; i<z; i++){
      if (x === undefined){}
    }
    console.info('t1 ', Date.now() - start);
    start = Date.now();
    for (var i=0; i<z; i++){
      if (x === void 0){}
    }
    console.info('t1 ', Date.now() - start);
})(Date.now(), '', 1e6)

Actually, I just realized the difference between void 0 and undefined . 实际上,我刚刚意识到void 0undefined之间的区别。 undefined is a value on global scope and void is an operator. undefined是全局范围的值, void是运算符。 What's happening in this test is that undefined was being checked globally whereas void 0 , since it is an expression using the operator void , does not require scope traversal in order to check its value. 在这个测试中发生的事情是undefined被全局检查而void 0 ,因为它是一个使用operator void的表达式,不需要范围遍历来检查它的值。 If you pass in undefined to the IIFE wrapper, the test results will be the same. 如果将undefined传递给IIFE包装器,测试结果将是相同的。 The performance discrepancy shown in the original test actually only measured the time-cost of scope traversal 1e6 times. 原始测试中显示的性能差异实际上仅测量了范围遍历1e6次的时间成本。

Further code proof that this is the case. 进一步的代码证明是这种情况。 The for loops below have the same execution time: 下面的for循环具有相同的执行时间:

(function(start, x, z, undefined, c, Math){
    for (var i=0; i<z; i++){
    if (x !== undefined){
        c = Math.random();
    }
    }
    console.info('t1 ', Date.now() - start);
    start = Date.now();
    c = 0;
    for (var i=0; i<z; i++){
        if (x !== void 0){
            c = Math.random();
        }
    }
    console.info('t1 ', Date.now() - start);
})(Date.now(), '', 1e6, undefined, 0, Math)

rock star does make a good point that the results are subject to how your code is written, such as whether the conditionally assigned values in memory are accessed or not. 摇滚明星确实很好地说明结果取决于代码的编写方式,例如是否访问了内存中有条件指定的值。 Based on my tests, it will vary a lot if you take the values and pass it as an argument to a function. 根据我的测试,如果你取值并将它作为参数传递给函数,它会有很大的不同。 At that point the browser may decide to do fewer optimizations. 此时,浏览器可能决定进行更少的优化。 Nevertheless, in every test I've run void 0 is still faster than or equivalent to undefined , uses less kb, and it removes concerns about traversing scope. 尽管如此,在每个测试中,我运行void 0仍然比undefined更快或等效,使用更少的kb,并且它消除了对遍历范围的担忧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM