JavaScript spin-off asm.js brings web even closer to native performance

Firefox creator Mozilla release benchmarks showing that asm.js, its performance-optimised subset of JavaScript, can deliver performance only 1.5x slower than code compiled to run natively.

JavaScript performance has come on in leaps and bounds in recent years but still lags some way behind code compiled to run natively as binary.

Firefox creator Mozilla claims to have narrowed the gap between JavaScript and native code performance through improvements to asm.js – delivering performance only 1.5 times slower than that of native.

asm.js is a subset of JavaScript that is optimised to maximise performance. asm.js is JavaScript and so will run in any browser but to get the best performance a browser's JavaScript engine needs to have been written to take advantage of the optimisations asm.js makes possible. Currently the only browser to support asm.js optimisations is Firefox, since Firefox 22, although Google has expressed interest in adding support to Chrome.

Mozilla's latest benchmark shows a significant improvement in the performance of asm.js over figures released earlier this year. At that point asm.js was delivering performance closer to 2x slower than native.

Mozilla achieved the performance increase by tweaking both Firefox's Spidermonkey JavaScript engine and the emscripten compiler, which generates asm.js code from C++. Unlike JavaScript the structure of asm.js is not easily readable by a human and asm.js is not designed to be written directly, but rather compiled from another language such as C or C++.

One change that led to "substantial speedups" in the performance of asm.js was introducing support in Firefox for carrying out floating-point operations using 32-bit floats rather than 64-bit doubles, which allowed Mozilla to add the float32 format to asm.js' type system.

Tests by Mozilla show Firefox with float32 optimisations can run benchmarks at around 1.5x slower than native. The red bars (firefox-f32) represent Firefox running on emscripten-generated code using float32. Run times are normalised to clang, so lower is better. Image: Mozilla

Mozilla points out of the peformance natively compiled code is not based on a single measure but a range, with different native compilers - in the case of this benchmark the C compilers clang and gcc - delivering code of differing performance.

"What this shows is that "native speed" is not a single number, but a range. It looks like asm.js on Firefox is very close to that range – that is, while it's on average slower than clang and gcc, the amount it is slower by is not far off from how much native compilers differ amongst themselves," Mozilla researcher Alon Zakai said in a blog post.

float32 code generation is off by default in the emscripten compiler, which Mozilla says is intentional as it can decrease performance when asm.js is run by JavaScript engines not supporting the Math.fround function (part of the proposed EcmaScript 6 specification). Mozilla hopes to enable float32 optimisations by default in emscripten in future.

While asm.js has Mozilla's backing, other major browser makers are looking to other technologies for improving the performance and/or maintainability of browser code, Google with NaCl and Dart, and Microsoft with TypeScript.

Zakai said there is plenty of scope to continue improving asm.js' performance.

"Even the current performance numbers – 1.5x slower than native, or better – are not the limit of what can be achieved, as there are still big improvements either under way or in planning, both in emscripten and in JavaScript engines," he said.