The focus of this release was on making the generated code faster. As the chart shows, we went from being 100X slower than hand-optimized JavaScript code, to around 5X slower. You can see the difference in the raytrace demo, which has been updated to use all the current optimizations.
5X slower is still slower. It will be hard to do much better, though, without either better JS engine support, or much more clever code analysis. Both will hopefully happen over time. Meanwhile, 5X slower is not too terrible, and there are some advantages over hand-written code - we hardly use garbage collection, so no GC pauses. Also, the speed really depends on the code - the comparison in the chart above uses benchmarks for which we have comparable code in both C++ and JavaScript. But the most interesting uses of Emscripten are to convert code for which we don't have a JavaScript equivalent. Also worth mentioning is that it is perfectly possible to hand-optimize the crucial parts of the code that Emscripten generates.
Some technical details about the optimizations implemented in this release:
- Use typed arrays, if available in the JS engine (thanks to pcwalton and njn for the idea)
- Optimize after the relooper runs, removing unneeded code flow overhead
- Nativize many more variables than before (i.e., move them off the emulated stack, and into native JS variables)
- Optimized stack emulation
- Inlining of various runtime code fragments
- Integration with the Closure Compiler: We generate output that it is very good at optimizing (thanks to Anders Riggelsen for the idea)
Also added in this release is support for the brand-new LLVM 2.8. That is now the version being tested against.