What is Web Assembly??? How fast it is compared to JavaScript?

Charles Rajendran
Ascentic Technology
5 min readMay 10, 2020

It’s always better to start with some statistics, according to the StackOverflow survey, javascript is the most popular programming language in the world. There are a number of reasons for this, such as the number of libraries, frameworks, tools available for the language, large developer community, tech giants involvement, it’s ubiquitous nature (we can develop applications for different platforms using javascript, from the client-side, server-side, mobile to raspberry pi, blockchain, machine learning development can be done through javascript) and so on. But the major reason for its popularity is, JavaScript is the language of the web.

Javascript played a monopoly role in the client-side programming paradigm all these years, many technologies almost died because of javascript, such as flash and java applets. Google Dart is considered as a replacement for javascript when it was launched, but it wasn’t able to replace javascript. In this web programming race, now we have new a sensation which is called the Web Assembly.

If we consider something to replace another, then it should have something special right. So why web assembly is better than javascript, the most important advantage web assembly has over javascript is, it’s speed, web assembly is extremely fast. Obviously the reason is, web assembly is a low-level language, which eliminates the time for compilation.

But let’s forget about the replacement of javascript for a moment, as a Javascript developer, now my intention is to find a way to integrate both web assembly and javascript together. Think of a scenario, where I am developing a javascript application, and I need to run a compute-intensive function which will take a lot of time to execute in javascript, then how good it would be if we could replace that function with web assembly and call it with javascript. This is the aim of this blog post.

In this post, I will write a function which will loop 1 billion times with both in javascript and in web assembly. Then I will compare the time both javascript and web assembly took to execute the code. Even though the function is practically useless, it will be enough for you to understand the power of web assembly and how much it is useful to integrate with Javascript.

Let’s start,

Step 1: Write the function in Javascript.

function jscounter() {
for(var i = 0; i < 1000000000; i++);
return i;
}

Quite straight forward, isn’t it. I have a function which will loop 1 billion times, So let’s write the same function in web assembly.

Step 2: Write the function in Web Assembly.

Writing functions in web assembly might be difficult since the language is low level, but the good thing about web assembly is, we can write the code in common languages such as C, C++, Rust (static type languages), and then convert it into web assembly by some tools.

But in this article, I have used an online c++ to wasm converter.

As you can see in the above image, I have written the function in C++ and compiled it, then it will provide you with the equivalent web assembly code and then you can simply download it and use it. Once you download the code, you can read the wasm file and work with that.

Step 3: Integrate web assembly and Javascript.

function LoadAssembly(asmFile) {
return fetch(asmFile)
.then(response => response.arrayBuffer())
.then(bytestream => WebAssembly.compile(bytestream))
.then(module => new WebAssembly.Instance(module))
.then(instance => instance.exports._Z12countBillionv)
}

In the end, this LoadAssembly function will return the web assembly function to your Javascript code which then can be used just like any other normal javascript functions.

Let’s go through the code step by step, I have already downloaded the wasm file to my project folder, then I made a fetch request to the file, fetch will return a promise with the response object, the response object will have the web assembly file’s byte stream which can be read by the arrayBuffer() function of the response object and then it will return another promise with the read byte stream, then in next step, the byte stream will be compiled and will produce a web assembly module which again will return another promise with the compiled web assembly module, then we will create an instance of that compiled module, with that instance we can use all the functions in that Web Assembly module.

Finally, we need to know the function name that we need to call, to find that we can use the web assembly code, if you see the above image, look at the place where it says export <function_name> func and find the function name in the middle (in our case _Z12countBillionv). Finally, we have reached the end of the LoadAssembly function, where we have returned the web assembly counter function.

Let’s call the LoadAssembly function,

LoadAssembly('billion-counter.wasm')
.then(counter => {
counter();
});

As you can see above, we have called the LoadAssembly function and it will return the web assembly counter function, finally, I have executed the returned function.

Step 4: Evaluating the performance difference.

To evaluate the time it takes to execute the function, I have used the time functions of the console API.

First, let’s evaluate the javascript function.

console.time('js-counter');
jscounter();
console.timeEnd('js-counter');

Then let’s evaluate wasm function.

console.time("wasm-counter");
LoadAssembly('billion-counter.wasm')
.then(counter => {
counter();
});
console.timeEnd("wasm-counter");

The final result is

js-counter: 525.392822265625ms
wasm-counter: 0.52587890625ms

As you can see in the above code, JS counter function has taken around 525.39 ms, where the wasm function has just taken 0.52 ms. In this case, the web assembly code is nearly 1000 times faster than the equivalent Javascript code, this ratio might change, but definitely the web assembly code will be much faster than the Javascript code.

Finally, to wrap things up, it would be better to give some practical applications developed with web assembly.

  1. Construct 3 Web Game Engine.
  2. City Bound
  3. Pyodide
  4. Doom3 Game

Final thoughts: All these years, we have written server-side code for running compute-intensive applications, but with the current web standards such as Web Assembly, Web GPU and etc, the gap seems less and less. So it’s our responsibility as a developer to utilize these features to write high performance, in-browser applications. That’s it guys, cheers 😉.

Note: All my code is available in Github and feels free to follow me on Github 😉.

--

--