WebAssembly: C/C++ In The Browser

Since I’ve been immersed in C/C++, I thought it would be a good time to try WebAssembly.

What is WebAssembly? It’s a new browser API that allows you to send over bits of compiled code to the browser for execution. I was originally hesitant about pursuing WASM because the toolchain looked painful. But thanks to an online tool, that part was made incredibly simple:  https://mbebenita.github.io/WasmExplorer/

We start with some hand-written C/C++ code like this:

Then that C/C++ code gets compiled to WAT format, which is a bit more descriptive about which data types will be used:

There are 2 notable things about the WAT file: it shows you that 32-bit ints will be used. That can be changed to i64 if you want to use 64-bit ints. You’ll also see that it exports a function called “fib”. Depending on your compilation settings, the name might look different- such as “_Z3fibi”- if you’re compiling a debug version. We need to use that name in the JS script.

Next up, the WAT file gets compiled into assembly- which you really don’t need to look at unless you enjoy self-inflicted torture. From there, we download the final WASM file which we’ll load via a JS script:

We fetch the wasm file as an array buffer, compile it into a module, then create an instance of the module. The module instance is an object with the exported functions. Our “fib” function is there. From there, you can call the function and get a return value just like any regular JS function.

I made a demo project in which the C and JS versions of the Fibonacci function were benchmarked. I saw a 1.7x to 1.8x improvement in speed in favor of the C version: https://github.com/ryanbennettvoid/c-stuff/tree/master/src/wasm

As mentioned earlier, my primary concern was build process. In the same way game engines make the work of a game developer easier, build tools like Webpack make the job of a web developer easier. And by the looks of it, there’s already a WebAssembly plugin for Webpack: https://github.com/ballercat/wasm-loader. My fears have been put to rest.

My early impression of WebAssembly is that it’s a pretty awesome extension of the web. It’s not meant to replace JS, but it’s a way of improving performance for demanding parts of the client side app. Since the dawn of web applications, we’ve tended to put the heavy number crunching logic on the backend so that slower devices don’t suffer. Well with WebAssembly, perhaps we’ll see a paradigm shift where we load more work onto the client, which can result in both a snappier experience and less server load. Since C/C++ has excellent static analysis tools, the code would be potentially more stable too. While I initially felt “blah” about WASM, I think the ROI is certainly a net positive for the future of web.

This awesome article inspired me to give WASM a shot: https://medium.freecodecamp.org/get-started-with-webassembly-using-only-14-lines-of-javascript-b37b6aaca1e4

Leave a Reply

Be the First to Comment!