开发者

Is Subtracting Zero some sort of JavaScript performance trick?

开发者 https://www.devze.com 2022-12-27 14:15 出处:网络
Looking in the jQuery core I found the following code convention: nth: function(elem, i, match){ return match[3] - 0 === i;

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

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

And I was really curious about the snippet match[3] - 0

Hunting around for '-0' on google isn't too productive, and a search for 'minus zero' brings back开发者_如何学编程 a reference to a Bob Dylan song.

So, can anyone tell me. Is this some sort of performance trick, or is there a reason for doing this rather than a parseInt or parseFloat?


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". :)


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

Is Subtracting Zero some sort of JavaScript performance trick?


(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.


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);


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.


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 (===)


If it's not an old relic that got lost, then it just tries to change the type to Number.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消