Cobertos

Is WebAssembly faster than vanilla Javascript?

I keep seeing GitHub issues of people just like me trying to figure out what WebAssembly (Wasm) and previouslyasm.js mean for performance-related javascript (in my case, games). WebAssembly should introduce less abstraction between you and the hardware and so your code should in general run faster, right? In reality this question is harder to answer because WebAssembly runs in a Javascript VM-like environment and was not made directly motivated for performance. I'll be putting aside the misinformation and anecdotes to hopefully find out if and how applying Wasm might make your projects more performant.

A bit of background on Wasm

200px webassembly logo

Wasm was originally created for so much more than just performance. Wasm is about providing a proper compile target for native code to get into the browser. In the earlier stages of the development cycle, Wasm was actually asm.js, a unofficial JavaScript standard that only supports strict subset of JavaScript to allow native code to compile and run in a JavaScript VM. Wasm is also about providing an environment where multiple sources of code can run safely at a low level where things like memory management and control flow structures (jumping and loops) matter. Already Wasm is doing a ton of things that previously were infeasible or a real pain to do in the browser. (Sourcing a lot of this from this blog post by Adrian Colyer. It's good to keep this in mind while we ask performance only questions.

Wasm loads much quicker than Javascript code in pretty much all cases I've seen that is not really a topic that's up for debate so I'll skip over load performance and focus on runtime performance.

After quite a bit of searching and review, I found a few people who have done research into Wasm's runtime performance specifically by using benchmarks:

  • In a joint Google, Mozilla, Microsoft, and Apple paper (May 2017) (also mentioned in that blog post by Adrian Colyer updating the wider Internet community, Wasm was found to perform close to but still less than C code for runtime of certain benchmarks. Taking test cases from the PolyBenchC library, the paper found that Wasm ran within 2x of native speeds in most cases and for some within 10%. I don't think you're going to get much better than that given the use case of Wasm and it being more abstracted and safe than actual compiled C code. The paper also found that Wasm is 33.7% faster for these same test cases than asm.js (which was already faster than javascript).

  • Alon "Kripken" Zakai, a Mozilla engineer and creator of both Emscripten (LLVM to Javascript compiler) and Ammo.js (port of Bullet Physics to Javascript and Wasm), has also written about Wasm vs asm.js (March 2017), calling out multiple features that Wasm can use over asm.js and the future of what Wasm can add. And while he provides lower estimates (specifically, 5% speedup between Wasm and asm.js) this is due to testing asm.js that was ported to Wasm, and not direct Wasm compilation.

  • The game engine Unity3D has seen improvements in using Wasm in a 2018 benchmark over their 2015 asm.js benchmark. Their 2018 post goes quite into detail over a lot of little changes they've observed.

  • An engineer from Samsung performed a similar benchmark (May 2018) with matrix multiplication, providing multiple implementations with different optimizations. And while he found Wasm to be faster for larger array sizes, he concludes that for normal web development, it's probably smart to stay with normal Javascript for now.

  • One final article to check out.

This gives me a good feeling. Wasm will give you some performance increase but only for applications with datasets that require it. Building websites probably won't be moving to Wasm anytime soon.

For those of us that do want to use Wasm from Javascript for games, realize that Wasm isn't meant for a dynamically-typed, garbage-collected language like Javascript. Typescript gets you closer to a Wasm compatible language but it looks like Javascript has it's own flavor now for Wasm, AssemblyScript, a stricter/modified Typescript. This article discusses other options for running Wasm from Javascript.

Vue.js render() and $slots; Corrupt DOM

Just ran into an issue today when making a component with a custom render() function and messing around with…

Chemistory Level and Net Code

Chemistory over the past couple weeks got a few new features, the biggest being an actual level and client/…