Hacker News new | past | comments | ask | show | jobs | submit login

> It requires only additions, subtractions and bit shifts: 2x is the same as x<<1, of course. It also requires only integer arithmetic.

Does any of this mean anything in JS, where AFAIK there are no real ints? 2x is an fpu operation under the hood, and not a bit shift.




IEEE double-precision floating-point numbers can exactly represent 53-bit integers and hence they are suitable for most integer related operations (ignoring bitwise operations).

For bitwise operations, JavaScript will first convert the number to a 32-bit two's complement signed integer.


I guess the question is really whether JS takes advantage of these facts.

Will JS, at runtime, realize that X is an int and optimize 2 * X into a bit shift operation?

Will JS recognize that Y and Z are perfectly represented integers stored in floats and so use integer instructions when adding Y + Z? Would such a thing even save time with all the casting back and forth to fp?


I think, using the `(…) | 0` (expression binary ORed with zero) construct most JS engines will use true integers in optimized code.


In fact, the specification even guarantees that for all the bitwise operators.


However, this is relatively new and there may still be some legacy engines around.


That goes back to at least ECMAScript 1 in 1997. Possibly further. Not sure there are that many legacy engines from before that still around.


Oh, I thought this came only with what was related to EMScripten before WASM (I forgot what the fast optimization standard is/was called). This took some years to propagate to all browsers.

As for interpreted JS, a binary operator returns a 32-bit integer value, but it would be still stored as a Number (float). (Meaning, a | 0 => int, b = a | 0 => float stored in b, there is no other primitive numeric type. – Instead of optimizing for speed, you would be adding implicit type conversions.)


Ah, now I get the confusion. Yeah, most of interpreters probably wouldn't have made the in-memory distinction between small ints and doubles. So the conversion would have to happen back and forth every time a bitwise operator would be applied.

Nowadays the semantics if what happens are still the same, but things happen a bit more optimized by usually avoiding the round-trip to double when not necessary.


Isn't there even a formal specification that hot code maintains values or-ed with zero internally as integers?

(I think, this had been originally introduced by Mozilla and propagated to other browsers to varying extent. This optimization allowed a significant speed up for things like EMScripten before WASM.)


Yes, asm.js, which by now has been abandoned and superseded by WebAssembly. And while Chrome never really supported asm.js, they added some optimizations that benefitted code written in that style.

I think that may also have been a problem with asm.js. While the code would work as is because it's just JS, you won't get any performance guarantees because the runtime could just do its own thing instead of doing ahead-of-time compilation to optimized code.


ASM is what I was looking for – thank you!


Funny enough JavaScript now has BigInt, which is purely integer:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...


It also has typed arrays (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Type...), but you can’t calculate with those values (you write floats into them that get rounded to integers, and values conceptually become floats when you read them)

WebAssembly has i32 and i64.


JS VMs have real ints (and you can summon them smi reliably usually with |0 ), but you're very much better off calling into some browser capability that will leverage the gpu most of the time.


I guess JS is only used as a tool to demonstrate the algorithm.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: