`a = 0-x` is about 3-10x faster than `a = -x` 🤯
Let's jump into JavaScript VM details to see why and how to guard against this VM de-opt:
🧵🪡🧶 https://t.co/WFfpPvfuXB
The first thing to understand is that JavaScript has two representations for numbers:
- Integers: Fast path
- Floats (IEEE 754): Slower path
Integers are stored as “Two's complement” and can't have `-0`, but Floats can! https://t.co/oWob4ylJPV
Let's assume: `x` is an Integer and `x = 0`
`0-x` => `0-0 => 0`, Result is `0` (Integer) Perfect!
`-x` => negate `x`.
- For any non-zero value, the result is an Integer.
- But for `0`, the result is `-0`. But integers can't have `-0`, So JavaScript stores it as a Float `-0`. https://t.co/rOczD1JV1f
Why is this a de-opt:
1) Array access requires an Integer. So VM has to guard for Floats and convert Float (-0) into Integer(0);
2) VMs have special "fast" arrays for all integers but use a more generic (slower) array for an array of mixed types (such as Integers and Floats) https://t.co/hxy5u9hoJU
Different browsers have different perf penalties for this, but my tests show a 3-10x slow down on Apple M1:
Try it yourself: https://perf.builder.io/?q=eyJpZCI6Inh0a3l0czhvbDY5IiwidGl0bGUiOiJGaW5kaW5nIG51bWJlcnMgaW4gYW4gYXJyYXkiLCJiZWZvcmUiOiJjb25zdCBkYXRhID0gWzAsIDFdO1xuY29uc3QgZGF0YUludCA9IGRhdGEubWFwKHY9PjAtdik7XG5jb25zdCBkYXRhTWl4ID0gZGF0YS5tYXAodj0%2BLXYpO1xuXG5jb25zdCBsZW5ndGggPSAxMDA7XG5jb25zdCBpZHhJbnQgPSBbXTtcbmNvbnN0IGlkeE1peCA9IFtdO1xuZm9yKGxldCBpPTA7IGk8bGVuZ3RoOyBpKyspIHtcbiAgaWR4SW50LnB1c2goaSUyKTtcbiAgaWR4TWl4LnB1c2goLShpJTIpKTtcbn1cbiIsInRlc3RzIjpbeyJuYW1lIjoiSW5kZXggYXJyYXkgd2l0aCBJbnQiLCJjb2RlIjoibGV0IHN1bSA9IDA7XG5mb3IobGV0IGk9MDsgaTxsZW5ndGg7IGkrKykge1xuICBzdW0gKz0gZGF0YUludFtpZHhJbnRbaV1dO1xufSIsInJ1bnMiOltdLCJvcHMiOjQyOTkyMH0seyJuYW1lIjoiSW5kZXggYXJyYXkgd2l0aCBGbG9hdCIsImNvZGUiOiJsZXQgc3VtID0gMDtcbmZvcihsZXQgaT0wOyBpPGxlbmd0aDsgaSsrKSB7XG4gIHN1bSArPSBkYXRhTWl4W2lkeE1peFtpXV07XG59IiwicnVucyI6W10sIm9wcyI6ODc4NjB9XSwidXBkYXRlZCI6IjIwMjMtMDItMTVUMjE6NTQ6NDQuOTcwWiJ9 https://t.co/0AstIgj6u3
Learnings:
- Avoid using the negate operator `-x`!
- Prefer the subtraction operation `0-x` to get a negative number! https://t.co/yNSKFJcGxA
Oops, there was a mistake! The conclusion and explanations are valid, but the slow down is not as bad.
But check out the explanation with the details.
https://twitter.com/mhevery/status/1626259524930932745?s=20