Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is parseInt() so much slower than *1 in Firefox?

I have a value stored as a string, and I know it will always be a whole number. But I need it as a number, so I was doing n = n * 1. Then I thought "hmm, I should probably just use parseInt(). Then I ran some jsperf tests, and the results in Firefox were interesting:

http://jsperf.com/parseintx1

Across the board, it appears the operations are pretty similar, except in Firefox, using *1 is exceptionally faster. What's going on here?


Edit

Someone made the base 10 test, and updated the tests overall. Click away on this one too to give some extra feedback: http://jsperf.com/parseintx1/2

like image 327
hookedonwinter Avatar asked Aug 28 '12 16:08

hookedonwinter


People also ask

Is it better to use number or parseInt?

For example ifyou want to convert a string with pixels on it to just a number, like 32px to 32 , then you should use parseInt , but most of the times you better stick with Number instead.

What can I use instead of parseInt?

parseFloat( ) parseFloat() is quite similar to parseInt() , with two main differences. First, unlike parseInt() , parseFloat() does not take a radix as an argument. This means that string must represent a floating-point number in decimal form (radix 10), not octal (radix 8) or hexadecimal (radix 6).

What does parseInt () function do?

The parseInt function converts its first argument to a string, parses that string, then returns an integer or NaN . If not NaN , the return value will be the integer that is the first argument taken as a number in the specified radix .

What is the difference between parseInt and number?

Differences. Number() converts the type whereas parseInt parses the value of input. As you see, parseInt will parse up to the first non-digit character. On the other hand, Number will try to convert the entire string.


2 Answers

I'm not a JavaScript engine expert by any means, or even a compiler expert, but I'm pretty sure that it boils down to the fact that the compiler can tell that this:

var a = "123";
a = a * 1;

is really exactly the same as:

var a = 123;

Because "a" is a local variable, and is unused from the point of its initialization to that * 1 expression, there's no point generating code to carry out the operation at all. After that point, the compiler may also be able to tell that there's no way that "a" can "escape" from the function, so there's really no point doing anything; that is, it may be that the * 1 test ends up with something equivalent to what you'd get from:

function() {}

In the parseInt() case, however, the compiler can't be sure that parseInt() is really parseInt(), as it may have been redefined. Thus, it has to generate code to make the function call.

like image 172
Pointy Avatar answered Oct 18 '22 17:10

Pointy


It has to be the test setup, since this version gives the expected result in Firefox too. The thing, in your setup I think, is that parseInt is applied (well, in FF at least) in every iteration to every variable, whereas the conversion from String to Number may be applied the first iteration in the multiplication test, after which the variables are numeric and multiplication needs no conversion anymore.

In version 7 the variables are assigned in the test setup, and the test assigns new variables at every iteration. Now both tests have 'equal changes', and parseInt outperforms the multiplication test.

After inspecting the test in IE[8,9] and seeing its results look like those of FF I think there's an explanation for the Chrome results: I'm pretty sure Chrome/Webkit has a better optimization in the first version of the test (especially the parseInt part), which gives a better result for parseInt there. It may be the precompilation of (parts of) the code in the V8 engine, used in those browsers.

like image 24
KooiInc Avatar answered Oct 18 '22 18:10

KooiInc