Is Subtracting Zero some sort of JavaScript performance trick?

前端 未结 7 1180
一向
一向 2020-12-06 00:32

Looking in the jQuery core I found the following code convention:

nth: function(elem, i, match){
    return match[3] - 0 === i;
},

And I wa

相关标签:
7条回答
  • 2020-12-06 00:58

    Just a info, According to this site

    using unary + operator is faster one than any of the following (which include '- 0'):

    var numValue = stringValue - 0;
    /* or */
    var numValue = stringValue * 1;
    /* or */
    var numValue = stringValue / 1;
    

    unary + operator also type-converts its operand to a number and because it does not do any additional mathematical operations it is the fastest method for type-converting a string into a number.

    This contradicts James' benchmark, although he may be might be correct. I think jQuery wouldn't utilise this syntax if it were slow.

    0 讨论(0)
  • 2020-12-06 01:04

    Various ways to coerse JS strings to numbers, and their consequences:


    (source: phrogz.net)

    I personally use *1 as it is short to type, but still stands out (unlike the unary +), and either gives me what the user typed or fails completely. I only use parseInt() when I know that there will be non-numeric content at the end to ignore, or when I need to parse a non-base-10 string.

    0 讨论(0)
  • 2020-12-06 01:08

    Probably just a short-hand way to force the left-hand side into integer. Not as clear as calling a function, of course.

    This tutorial on type-conversion states:

    Any mathematical operator except the concatenation/addition operator will force type-conversion. So conversion of a string to a number might entail performing a mathematical operation on the string representation of the number that would not affect the resulting number, such as subtracting zero or multiplying by one.

    This also reveals that "subtracting" is a better search term than "minus". :)

    0 讨论(0)
  • 2020-12-06 01:10

    Based on a few quick and dirty benchmark runs, "1234" - 0 was about 50% faster than parseInt("1234") and 10% faster than +"1234" in Firefox 3.6.

    Update:

    My "quick and dirty" benchmark was not very useful because it was just converting the string "1234" in a loop. I tried again using a random list of numbers, and the results are all over the map. The three methods are all within 400-500 ms on this computer except when they jump to 1300 ms! I think garbage collection is interfering. Here is some code to play with in Firebug, in case I did something stupid:

    function randomList() {
        var list = [];
        for (var i = 0; i < 1000000; i++) {
            list.push("" + Math.floor(Math.random()*4000000000));
        }
        return list;
    }
    
    function testParseInt(list) {
        console.log("Sanity check: parseInt('" + list[0] + "') = " + parseInt(list[0]) );
        var start = new Date();
        for (var string in list)
            var tmp = parseInt(string);
        var time = new Date() - start;
        console.log("parseInt(string): " + time);
    }
    
    function testMinusZero(list) {
        console.log("Sanity check: '" + list[0] + "' - 0 = " + (list[0] - 0));
        var start = new Date();
        for (var string in list)
            var tmp = string - 0;
        var time = new Date() - start;
        console.log("string - 0: " + time);
    }
    
    function testUnaryPlus(list) {
        console.log("Sanity check: +'" + list[0] + "' = " + (+list[0]));
        var start = new Date();
        for (var string in list)
            var tmp = +string;
        var time = new Date() - start;
        console.log("+string: " + time);
    }
    
    function testPlusZero(list) {
        console.log("Sanity check: '" + list[0] + "' + 0 = " + (list[0] + 0) + " Oh no!");
        var start = new Date();
        for (var string in list)
            var tmp = string + 0;
        var time = new Date() - start;
        console.log("string + 0: " + time);
    }
    
    
    var numbers = randomList();
    
    testParseInt(numbers);
    testMinusZero(numbers);
    testUnaryPlus(numbers);
    testPlusZero(numbers);
    
    0 讨论(0)
  • 2020-12-06 01:16

    It really looks like a "performant" parseInt to me.

    0 讨论(0)
  • 2020-12-06 01:19

    Your main reason to use this syntax is if you have generic code that may be any number (int or float) and you want to do a type-sensitive compare (===)

    0 讨论(0)
提交回复
热议问题