Comparing the performance of Math.floor(), parseInt and a (bitwise) shift
Wed, May 30, 2012
Note: Sorry, this post might be a bit more technical than usually.
I wasn't surprised that parseInt was slow, since I think it parses the number as a string, but the left/right shift being faster than Math.floor() was a bit more puzzling to me.
So I decided to make a JSPerf test to compare those three methods.
There are only a handful of browsers that have been tested, but it seems that the left shift is indeed faster in at least Firefox, my Android browser and in Internet Explorer.
V8's internalsMy good friend, Paul Rosania (who's blog you should read), looked at the V8 source to look at what it's doing internally. Math.floor() does seem to be implemented using the bitwise left shift operator.
What is a left shift and how/why does it work?If you are not familiar with bitwise operators, they are are used for doing bit-level computations on variables. Anything you do with them is usually very fast, since it's one of the most simple operations you can do (internally all operations, such as subtraction, division, multiplication etc are done using bitwise operations.)
I'm not going to bore you with bitwise math, there are plenty of posts about those. This one on the MDN site is pretty detailed so I recommend that as a good read.
But as a super-quick overview, a left shift moves all the binary values of a number one slot.. so 25 left shifted 2 slots becomes 6:
or:25 >> 2> 6
So, the burning question on your mind is probably what happens when you perform a bit wise operation on a floating point number? Excellent question.011001 << 2> 000110
So doing any left shift on any floating point number results in it getting converted to an integer first. A left shift of 0 shifts the thing zero slots. So the only thing that *actually* happens is that
Caveat of using a left shift to round a floatOf course you should be aware that the bitwise operation will only work for floats that are smaller than 2147483648 (0x80000000) or the number will actually become negative, since the first bit is used for the signing (negative or positive number).
I hope this was interesting.
If you have an suggestions or correction etc, feel free to comment and I can amend the article and claim full credit. Thanks.