I found similarly "meh" performance improvements when trying to port my Javascript code to webassembly: either modern Javascript implementations are absolutely amazing, or webassembly runtimes still have a ways to go.
I found similarly "meh" performance improvements when trying to port my Javascript code to webassembly: either modern Javascript implementations are absolutely amazing, or webassembly runtimes still have a ways to go.
Typed arrays are mainly faster in scenarios where you allocate one or a few large TypedArrays once and then re-use them a lot.
That also explains your experience with many small arrays. That's basically the worst way to use TypedArrays.
let a = 1; let b = 2; let c = a+b|0; // c is guaranteed to be a 32 bit signed integer
This not only ensures correct 32 bit integer semantics (like wrapping around), but also helps the engines to use actual integer instructions in the generated machine code.
For unsigned 32 bit integers, there is `>>>0`, and for multiplication, there is Math.imul().
But there is only one type of number in javascript. Everything is just a double(BigInt aside). You get a 32-bit integer because the bitwise operator casts the result to one. c has the exact same semantics as any other js number.
Yeah there are tricks to convince the engine you are using an integral type but those unless you are doing a lot of benchmarks they aren't really useful. Any compilation tier can choose to use any intermediate representation it wants.
There is nothing stopping JS engines from trying to infer when a number is only an integer and optimize for that. In fact, that's what Small Integer (SMI) optimizations are all about[0].
It's just that |0 isn't really able to guarantee that our number value is the type of SMI that V8 optimizes for (since the V8 SMIs are 31 bits, and bitmasking operations only guarantee 32 bit integers)
https://ponyfoo.com/articles/an-introduction-to-speculative-...