12 ms·
The point is to have a more efficient solution to deploy large scale Web applications. Efficiency here is measured in comparison to JavaScript, and it's based o
by apignotti 3y ago
The point is to have a more efficient solution to deploy large scale Web applications. Efficiency here is measured in comparison to JavaScript, and it's based on 3 main points
1. More compact representation due to binary encoding compared to text
2. Improved compilation times, since WebAssembly is "lower-level" compared to JS and the engines can assume code has been already optimized and can skip a good chunk of the normal JIT optimization pipeline.
3. Improved runtime performance due to strict typing. No type-checks, no bailouts, etc
These come with their set of drawbacks, the main one being that WebAssembly cannot _really_ use the DOM or interact with JavaScript directly and is effectively just a computational engine. Any interaction with the outside word is abstracted to "imports": calls with arbitrary semantics come from outside of WebAssembly.
At some point WebAssembly also had the advantage of predictable performance, with the idea being that code would be compiled once-and-for-all during module loading.
This promise was, as far as I understand, effectively abandoned first by the introduction of "Baseline" compilers (Liftoff, in V8 terminology) and in more recent times by the requirement of WasmGC, which (I think) has reintroduced the need for bailouts and dynamic recompilation.
- azakai 3y agoI wouldn't say that predictable performance was abandoned, but you are right that it is less of a strict guarantee these days: 1. Baseline compilers are generally 2x slower than optimizing ones. That's noticeable, but it is still a far smaller difference than JS has between its tiers. 2. Even WasmGC doesn't require bailouts - in fact no VM implements them for Wasm AFAIK. However WasmGC is often compiled by languages that do benefit significantly from dynamic inlining, which adds unpredictability, but again the effect (30% [0]) is far smaller than typical differences in JS. [0] https://v8.dev/blog/wasm-gc-porting https://v8.dev/blog/wasm-gc-porting
- UncleEntity 3y ago> This promise was, as far as I understand, effectively abandoned first by the introduction of "Baseline" compilers (Liftoff, in V8 terminology)... This, I don't understand... AFAICT the "baseline" compiler's entire job is to get pixels on the screen as fast as possible and then they use optimization strategies to recompile code sections or functions or whatever to speed it up based on $reasons.
- kevingadd 3y agoOne of the historical problems with JS for the kind of application WASM gets used for was that you had no way to predict how a given piece of JS would perform in each browser. The quality of the generated code was dependent on a ton of factors, and code could randomly get de-optimized during execution if you accidentally did something like pass a double into a function that had previously only been passed integers, despite the two being the same JS type. JS compilers are full of weird heuristics based on things like (I kid you not) how many characters are in your function's source code. WASM originally promised to be AOT compiled once, start to finish, with consistent performance. The design omitted some useful (perhaps essential) things in order to be able to provide this.
- endorphine 3y agoIs lack of GC another reason that wasm is more performant than JS? P.S. I assume JS has a GC and WASM does not.
- pjmlp 3y agoWASM now has GC support as well, https://developer.chrome.com/blog/wasmgc https://developer.chrome.com/blog/wasmgc
- daxfohl 3y agoNot really. Sure it adds some overhead but it's well optimized and not overly significant, especially for incremental collections. It can even pay for itself by defragging your memory, making subsequent allocations cheaper. The big problem with GC is the pauses it causes when doing full "stop the world" collections, which can be noticeable in animations, or even on server-side in high-volume latency-sensitive services. But there are strategies you can use to reduce or eliminate the need for those if you're willing to put in the effort (beyond the scope of this comment). Note that pauses _can_ happen in non-GC languages too, if you have to delete something that references a bunch of other stuff that you have to recursively delete as well, though in the real world this is not very common.
- crq-yml 3y agoGC changes the performance profile of allocations, specifically. If your code is written to use static memory you won't experience GC pauses, but languages like JS that employ GC intentionally steer you towards allocating to do, e.g. string processing, so you have to go out of your way to make JS fast in this way. WASM now has GC, since a goal is to support alternative scripting environments and e.g. run a mixture of Rust and Python code in the browser.