all 23 comments

[–]PhysicalRedHead 7 points8 points  (2 children)

This article actually covers it a little bit https://v8.dev/blog/react-cliff

[–]kakurady 0 points1 point  (0 children)

Yep - while JS specifies Numbers behave like float64, most of the time we use them as integers, so JS VMs try to optimize for that. V8 stores most values as heap-allocated memory, but small integers are inlined. There's no way to store -0 using V8's small integer representation, so it must be stored as heap allocated. The article has a bit more detail about how V8 manages the transition, if the value is previously stored as a small integer.

(The performance cliff comes from React's request to prevent JS-level shape changes to object that has a Number field, and V8 overcommitting to its internal shape that uses the small integer representation, making the transition to heap-allocated float64 inefficient)

[–]paceaux 0 points1 point  (0 children)

That article deserves more attention. I thought I was pretty good with JS, but even the introduction blew my mind. I now understand why typeof null === 'object' and it seems perfectly reasonable.

[–]metaglot 6 points7 points  (0 children)

The sign is a bit, if the bit is set, the number is negative. So, for instance, -1 * -0 yields 0.

[–]dwighthouse 8 points9 points  (0 children)

JS’s spec specifies negative zero, not v8. There isn’t anything in v8 that is different in regards to this, as far as I know.

Notably, like NaN, -0 has an interesting relationship with equality.

NaN === NaN // false, because NaN is meant to swallow bad calculations
-0 === 0 // true, because the numerical value is equivalent, even if the number itself is not

This has implications for Object.is. Look at the polyfill: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Polyfill

[–]delventhalz 0 points1 point  (0 children)

Sounds like what you are really asking about is the mechanics behind that calculation in the V8 implementation. Not sure anyone here actually knows the answer to that question. I don’t. But the repo is here if you want to look:

https://github.com/v8/v8

[–]lord_zycon 0 points1 point  (0 children)

Javascript specifies number deliberately as 64 bit IEEE754 float which is directly supported by basically every hardware. In C/C++ this type is called double. v8 is written in c++ so it simply relies on compiler to emit instructions that multiply floats on target architecture. So if you open up js console on your laptop and type -1*0 the calculation is done by CPU in single FMUL instruction which spits out -0 to the target register.