`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:

🧵🪡🧶
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!
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`.
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)
Different browsers have different perf penalties for this, but my tests show a 3-10x slow down on Apple M1:

Try it yourself: perf.builder.io/?q=eyJpZCI6Inh…
Learnings:
- Avoid using the negate operator `-x`!
- Prefer the subtraction operation `0-x` to get a negative number!
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.

• • •

Missing some Tweet in this thread? You can try to force a refresh
 

Keep Current with Miško Hevery (Builder.io/Qwik)

Miško Hevery (Builder.io/Qwik) Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

PDF

Twitter may remove this content at anytime! Save it as PDF for later use!

Try unrolling a thread yourself!

how to unroll video
  1. Follow @ThreadReaderApp to mention us!

  2. From a Twitter thread mention us with a keyword "unroll"
@threadreaderapp unroll

Practice here first or read more on our help page!

More from @mhevery

Feb 17
JSX could have been 2x faster if it was designed more optimally for JS VMs!

Let's see what design decisions make JSX slow and how we could speed it up.

🧵🪡🧶 Image
There are two issues with tcurrent JSX transpilation:

1. The use of object-literal for properties causes megamorphic access on read.
2. Using variable args requires conversion to an array in `h()` function. Image
Let’s try an alternative transpilation format:
1. Arrays are always monomorphic
2. Key/Value pairs can be stored at odd/even locations
3. Children are in an array Image
Read 6 tweets
Feb 16
CORRECTION: The explanation and conclusion are correct, but the benchmark had an honest mistake so the slowdown is only 20-50%.

Thank you, @mraleph, for catching it.

But let's turn this into a lesson and understand the mistake and why it caused such a drastic slowdown.

🧵
The mistake is that my array contained `[-0, -1]` when it should have contained `[-0, 1]`. Image
Except JavaScript never does what you think, and actually, negative indexes are OK! 🤯 Image
Read 5 tweets
Feb 14
Lazy loading in frameworks is a lie!

(And then we blame the developer for slow sites.)

🧵🪡🧶
Let's start with a simple app. Let's assume it is slow because of too much JavaScript.

Experts say there is an easy solution. Just lazy-load it!

I want to show you how much the frameworks will fight you every step of the way and how little benefit you will get.
The most obvious place to start is to try to lazy load the components. So let's do that.

Congratulations, you just made your app slower!
Read 10 tweets
Feb 12
Words are hard! And sometimes, they don't come out the way they were intended.

I feel this is such an example, so let me expand on what I believe:
Ideas are created when you talk to others/study existing solutions. We all stand on the shoulder of "others".

It is rare that we have genuinely original ideas. Most of the time, they are repackaging incremental improvements to what already exists.
Teamworks are essential! @adamdbradley , @manucorporat and the @QwikDev community are amazing! Before then, I was part of the Angular Team and community that were equally amazing. In both cases, things would not happen without them!
Read 8 tweets
Feb 10
useSignal() is the future of web frameworks and is a better abstraction than useState(), which is showing its age.

🧵🪡🧶
useState() returns the value "in time" rather than the state "over time" it represents. This can lead to problems when value is captured in closures such as useEffect().
useState() => value + setter
useSignal() => getter + setter

Value is problematic because you must remember to pass it down every time it changes. A getter (like the setter) never changes, and so it only needs to be passed once.
Read 5 tweets
Feb 9
useEffect is a bad abstraction

There is a better way: 🧵🪡🧶
useEffect() only runs on the client.

Sometimes I want to run code as part of SSR/SSG on the server.
useEffect() runs after rendering

Sometimes you may want to run before rendering to precompute data for the rendering.
Read 6 tweets

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3/month or $30/year) and get exclusive features!

Become Premium

Don't want to be a Premium member but still want to support us?

Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal

Or Donate anonymously using crypto!

Ethereum

0xfe58350B80634f60Fa6Dc149a72b4DFbc17D341E copy

Bitcoin

3ATGMxNzCUFzxpMCHL5sWSt4DVtS8UqXpi copy

Thank you for your support!

Follow Us on Twitter!

:(