The primary reason Math.floor
is slower (where it actually is--in some tests I've done it's faster) is that it involves a function call. No JavaScript implementation that I know of inlines function calls. In the best case, the engine will avoid the name lookups by caching the function or storing properties in a table, with a dynamic class instead of a hashtable. You will always have some function call overhead though.
If you encapsulate any of the other methods in a function, they will perform almost exactly the same as Math.floor
.
More importantly though, as was mentioned in several comments, the other methods are not equivalent. They all work by doing bitwise operations. The bitwise operators automatically convert their operands to 32-bit integers by truncating the number. That's fine if the number fits in 32 bits, but JavaScript numbers are 64-bit floats, which could be much larger than 2147483647.
They also give a different result for negative numbers, since converting to integers truncates and Math.floor
always rounds down. For example, Math.floor(-2.1) === -3
, but (-2.1) | (-2.1) === -2
.
If you know you are only dealing with positive numbers less than 2147483648, and you need to squeeze every bit of performance out of your code (make sure it's actually the bottleneck first), I would use an even simpler method: x|0
. It doesn't evaluate the variable twice, and it works even if x
is an expression (just be sure to put it in parentheses so you don't run into precedence issues).