WASM currently doesn't support SIMD and threading, other than that it is already close to single-threaded native performance (usually within 1.2x to 1.5x, there are some runtime checks happening after all).
Frankly, I would be surprised to see well-written Javascript code that's consistently 8x to 10x slower than (single-threaded, non-SIMD) native performance. You have spikes from GC and re-compilation, but JITed JS is not that slow.
WASM is not native code, so there's no guarantee it will have the same performance. There have been earlier attempts to have cross-browser and cross-platform native code execution on the web, not to mention plenty of nonportable web plugins, but WASM's just-in-time compilation of a low-level bytecode is a good balance between performance across different architectures and feasibility of sandboxing code execution (you don't want a web app to gain access to your filesystem and kernel syscalls with impunity)
As with any language, it depends on how good the optimizations are; wasm is designed to be able to be JITted fast, but is still fairly new, so there's still stuff left on the table.
Additionally if you're compiling a language to wasm, you're also at the mercy of that compiler as well, so it always depends.
Most wasm toolchains use clang for c/c++, so poor compiler generation is rarely a significant issue. IIRC, the emscripten toolchain uses musl as the C runtime, which is reasonably performant runtime. Of course, if you write algorithmically inefficient code, no toolchain is going to improve it.
I'm getting a steady 40 FPS on Firefox 56 and 58 on Windows 10. About 5 FPS slower on Chrome 62 on the same machine. And Vivaldi is almost identical to Chrome, which is expected considering they share the same internals. Impressive.
EDIT: ~640,000 particles on all browsers.
935040 particles at a steady 91 FPS, 1080p full screen (minus windows launch bar + tabs/frame of browser). This is in Chrome. I don't get the purpose of the site, though.
WebGL is a new frontier for many. I myself was impressed by what I could do with three.js at work. Also impressed by other three.js projects / products out there.
This isn't a guide for implementing an actual modern particle system, but rather the author's learning project/proof-of-concept for WebAssembly. The presented effect itself trivially translates to a fragment shader.
His post helped me demystify what WASM is capable of and how it fits with the DOM. He shares some eye-opening code snippets, but the game itself is closed source so it leaves something to be desired.
- single-thread CPU performance is pretty much 'good enough' now
- WebGL and WebGL2 too, but you have very different performance behaviour than a native GL driver (much higher call overhead for instance)
- pretty much all other HTML5 APIs: oh boy what a mess :/
Don't expect a 100 GB AAA Steam game to run on the web anytime soon, but mobile games will port over fine. It's better to define the web as your main platform, and design a new game from scratch around it's limitations.
So if you have a project which needs to do 3D rendering, audio, touch input etc... CPU performance is the least of your problems.
It's running on your browser's JavaScript VM (maybe in a special mode). The code compiled to WASM just like any other machine language. Quite a few compilers support WASM as a target now.
In general, there should be, but it depends on what you're doing. For example, wasm can't access the DOM directly yet, so you have to call back into JS to do it, which is much slower than the eventual native API will be. For stuff like this, though, it should have much lower overhead.
Parsing of WASM byte code is massively faster* than parsing JS source code, but calling back and forth between JS and WASM is an entirely different topic. It's not that slow though, for instance each call to WebGL incurs that overhead, but the overhead is small enough that it doesn't matter that much (for overall performance) compared to asm.js or "normal" JS code. Still, if you want the best performance, avoid as many calls into the JS side as possible (e.g. by eliminating redundant WebGL calls).
edit: * at least in Firefox, Chrome still has some... potential :)
> Wasn't the main point of WASM that it is faster to parse than JavaScript?
That is only one of the advantages of WASM. The major advantage is that seen by CPU-bound code sections where WASM can be efficiently executed at "near" native speed.
Conversely, this performance advantage is not enjoyed by I/O-heavy operations which will not see any major improvement versus regular JS - this is roughly due to the browser having to apply sandboxing/security/protection (or by just forcing you to make JS calls to achieve this).
It's possible to come up with a close result with JS, but with WASM you have a lot space to add more things on top than just moving a particle back to it's origin.
I'm also getting crashes in Safari tech preview. Firefox developer ed. and chrome canary both run it, but Firefox can handle about twice as much as Chrome at roughly 2 million particles while still getting over 40FPS. Chrome slows down a lot with anything over a million. This is on a 2014 MBP.
60 FPS in Firefox 57.0, Chrome 62.0.3202.89, and Safari 11.0.1, on a 2017 iMac running High Sierra (10.13.1) with a 3.4 GHz Intel Core i5 and a Radeon Pro 570 4 GB.
I get 23 fps at 1.8 million particles with a single gtx1070. Well, 17-24 fps but sits mostly at 23. Quite interesting to see the comparison between generations.
EDIT - The above was in Chrome. In Firefox I actually get 23/24 fps at 4k (3.83M particles). At 1.8M in Firefox I get 48-50fps. Pretty good from Firefox.
Doesn't seem hardware limited, CPU and GPU utilisation doesn't go above 20% and I'm running other stuff like a decent sized VM and some other programmes.
I really don't know much about WASM. Would these numbers be deemed good? Is there more performance to squeezed out? I'm guessing there is as it's not fully utilising the hardware?
That's odd, I'm running on a Macbook with an Intel Iris Pro integrated graphics card and I'm getting 60FPS. Using Chromium 62.0.3202.89 (Developer Build) (64-bit) though.
https://i.imgur.com/wbiUT5l.jpg
EDIT: Ah just noticed I'm only using 586k particles.
Quite interesting to read. I don't know much about WASM but I presume the big Uint8Array is the actual C program or something?