Smaller and faster WebAssembly from C++ compared with Emscripten

Today we are proud to announce the first release candidate of Cheerp 2.5 (2.5RC1), a major update to the Cheerp toolchain since the release of Cheerp 2.0 — the first release to support WebAssembly — one year ago.

Cheerp is an open-source, enterprise-grade C/C++ compiler to WebAssembly, JavaScript, or a combination of the two. It is a commercial alternative to the Emscripten toolchain, focused on providing better interoperability with JavaScript, support for generating garbage-collectable JavaScript, smaller WebAssembly build size and better performance.

While also based on the LLVM/Clang stack, Cheerp does not use the upstream LLVM WebAssembly backend, as Emscripten does. Cheerp is based on a custom extended Clang frontend and a custom LLVM backend.

We are strong believers in the WebAssembly ecosystem, and on the power of healthy competition in pushing the envelope of what is possible, particularly when it comes to performance and optimisations. We were therefore particularly interested to see Emscripten now being based on the LLVM WebAssembly backend for code generation, and excited to see if we could achieve better WebAssembly performance with Cheerp.

After one year of work, we are happy to report that on our benchmarks, Cheerp WebAssembly output is on average 8% smaller (11% smaller before gzip compression) compared to the latest release of Emscripten. On both Firefox and Chrome, WebAssembly code generated by Cheerp is 5–6% faster than Emscripten (16% faster if not excluding an outlier). Because Cheerp can compile to mixed JavaScript-WebAssembly output, it can circumvent the limitations of WebAssembly (such as direct DOM and WebGL/WebAudio access) without sacrificing its native-like speed.

We are proud of the performance we achieved with Cheerp 2.5, and think it now provides the gold standard for building WebAssembly applications. We are also among the most demanding users of Cheerp ourselves. All of the tools and products we make: CheerpJ (Java to JavaScript/WebAssembly) and CheerpX (WebAssembly x86 virtualization) are based on Cheerp, and each one of them is pushing the boundary of what is thought to be possible on the Web platform.

New in Cheerp 2.5

Cheerp 2.5 is the result of 12+ months of hard work by our development team. While this release does not introduce major new features, it is fully focused on quality-of-life improvements, cleaner code generation, and faster build times.

Cheerp is based on the LLVM/Clang framework. Since the 2.0 release, we have started a long term modernization effort to bring Cheerp fully on par with the upstream LLVM/clang project. The 2.5 release includes a first big step in this effort, as Cheerp has been rebased from LLVM/Clang 3.7 to the 6.0 version. This work will be ongoing for the next few releases, to finally rebase Cheerp on up-to-date LLVM/Clang. We are doing this progressively to make sure no regressions are introduced, for the sake of both the end-users of Cheerp, and for the sake of our other products CheerpJ and CheerpX.

Cheerp allows classes and functions to be tagged with optional attributes such as [[cheerp::genericjs]] , [[cheerp::wasm]] and [[cheerp::jsexport]] , instructing the compiler on the desired compilation behaviour, allowing to keep all information in a single place: your code-base. In WebAssembly mode, code runs faster but has limited access to browser APIs. In JavaScript mode conversely, the code may run somewhat slower, but full access to browser APIs is possible, as well as garbage collection. Cheerp is designed to give the user as much flexibility as possible, within the limitations of the platform, and always emits readable and meaningful error messages when something is not possible due to the current limitations of WebAssembly. Cheerp 2.0 was the first product in the market to provide this level of interoperability, but it’s the new 2.5 release that truly delivers on this promise. This feature support is now battle-hardened by one year of testing from our users and ourselves. With mature support for interoperability, it is now both possible and easy to write large scale real-world Web applications in C++.

Cheerp 2.5 includes several quality-of-life improvements for our users. The command-line options have been simplified and now WebAssembly is generated by default. Old command-line options are still fully supported and internally mapped to the new ones, for compatibility with existing build scripts. Compilation time has also been significantly reduced, especially for large codebases. Debugging should also be simpler as now the builds are fully reproducible: if you run the compiler twice on the same input, the output will be the same.

Many small improvements to WebAssembly code generation have also been implemented, which together sums up to an impressive reduction in code size, for the same (or better) performance.

To name a few interventions:

CFGStackifier v2. We implemented a fully redesigned unified algorithm to render the control flow in WebAssembly and JavaScript. For more info see our original post. Globalization. Cheerp now takes advantage of WebAssembly globals to encode constants and global data when convenient. Improved GlobalDCE. Cheerp now removes global data which, even if modified, does never alter the observable state of the program.

Benchmarks — Cheerp vs. Emscripten

The performance was evaluated on Google Chrome (standalone v8 — version 8.3.12) and Mozilla Firefox (standalone SpiderMonkey — version shipped with Firefox 74). The performance was compared with the latest release of Emscripten (version 1.39.11).

For the scope of evaluating this release candidate, we focused on the four largest (the zzz_ suite) test cases. These tests are part of Emscripten’s benchmark suite, we have sent a pull request to update the existing Cheerp support to the new command-line options in Cheerp 2.5.

Build Size

Size benchmarks are platform-independent. The total output size was compared after gzip- compression, which is better related to real-world download time over HTTP.

Build size with Cheerp vs Emscripten. Raw data is available at this address. Interactive charts available here. Uncompressed data is available at this address, charts here.

Compressed build size with Cheerp is on average 8% smaller compared to Emscripten, when combining both JavaScript and WebAssembly components.

Compared to Cheerp 2.0, this is an improvement of over 18% in raw size on average, making Cheerp the best-in-class tool for the generation of WebAssembly from C/C++.

We believe that these results show that our single-step, integrated codegen is a better approach to size optimization compared to Emscripten’s approach of codegen followed by a separate optimization step using wasm-opt.

Speed

Run time performance was averaged on three runs on a standard reference Linux machine. Similar results have been achieved on other hardware.

On Firefox’s SpiderMonkey engine, Cheerp 2.5 WebAssembly output is on average 5% faster than Emscripten (16% faster if not excluding an outlier). The zlib benchmark is 51% faster on Cheerp compared to Emscripten, suggesting some missed opportunities in Emscripten’s codegen on this specific test case, or perhaps a regression.

On Chrome’s v8, Cheerp 2.5 is 5% faster than Emscripten on average (16% faster if not excluding an outlier). The zlib anomaly can be replicated also on Chrome, with Cheerp 50% faster than Emscripten.

Run time performance of Cheerp 2.5 vs Emscripten on Firefox 74, average on 3 runs. Raw data is available at this address. Interactive charts available here.

Run time performance of Cheerp 2.5 vs Emscripten on Chrome v8, average on 3 runs. Raw data is available at this address. Interactive charts available here.

Getting started with Cheerp 2.5

Cheerp 2.5 is available for Windows, macOS and Linux. To get started with Cheerp, please visit the main Documentation page. You will find instructions on how to download, install and use Cheerp, as well as step-by-step tutorials.

Summary

Cheerp 2.5 is the result of one year of active development focused on optimisation starting from version 2.0.

With a build size on average 8% smaller compared to Emscripten, and performance 5% faster on average compared to Emscripten on both Chrome and Firefox, Cheerp 2.5 is now the best-in-class compiler for the generation of WebAssembly from C/C++.

Because of Cheerp’s unique capacity of compiling into mixed-mode JavaScript-WebAssembly, the advantages of WebAssembly (speed and size) can be combined with those of JavaScript (DOM and WebAPI access, garbage collection) on the same code base.

Get in touch

Cheerp is an actively developed project backed by Leaning Technologies, a company with years of experience in compile-to-JavaScript and compile-to-WebAssembly solutions, and a strong technical team that can provide support and professional services if needed.

Tested on millions of lines of code, chosen by many commercial products, Cheerp is the best technology to enable complex, large-scale applications to be converted to a Web application.

For more information on how Cheerp can help your organization to leverage your existing C++ code to develop HTML5 web applications that work on any device, with no need for plug-ins or download, please check out our website.

Follow us on twitter or drop us a line on Gitter! For additional technical information on Cheerp, please visit our wiki or our tech blog.