The WebAssembly Magic 🪄
Tags: webdev, programming, devops, performance
Published: 2024-06-30 15:08:51

Hello amazing people 👋,

Have you ever thought about running some other programming language on the browser, other than Javascript 🤔. But then thought it is not possible since Browsers natively support only Javscript right?

Now what if I tell you that WebAssembly is the solution here, it enables us to run any compiled programming language on the web with near native execution times. But how ??? Okay, now in order for you to understand this, let us first discuss about what WebAssembly is right? But hey, in order to understand what WebAssembly is let’s first look at how compiled languages work on any machine.

So languages such as C++, Java, Rust have their compilers which first convert this code in a low level syntax (mostly some assembly like language) and then that low level code can be executed natively on the machines. 

HLL (C++/Java/Rust) ———> LLL (Assembly) ———> Execution on machine.

Here can you a see a common thing ?? You guessed right, all the languages here gets compiled to some low level targets. And what if we define a low level target language which can be run on the browser ?? Well, WebAssembly is that only, it is a compilation target for high level languages which can be executed on the browsers.

But how is it possible to compile languages to WebAssembly, you might think. Well, we have different compilers in the WASM (WebAssembly) Ecosystem. One of the popular examples being Emscripten (EMCC) which is a compiler for C/C++ which compiles them into WebAssembly code.

But why do we even need to use WebAssembly in the first place, why can’t we simply compile these other languages in Javascript and then run them on browser. Well for many years, asm.js was a popular standard. But for many use cases we want speed and performance right, then what is the point of compiling faster languages to Javascript. That is why we want to achieve native speeds by directly running their low level targets on the Web.

Lets now understand the WebAssembly’s magic with a simple example:

Suppose we want to sort 1 million random numbers in the browser, but Javascript seems slow for this operation and we decided to implement this in C++ and then load its WebAssembly target code in the browser, then let’s see how much it can optimize the things. 

So, lets have this code in Javascript and C++ which sorts the 1 million random numbers and then also prints the time taken in sorting them.

```js
const arr = [];

for (let i = 0; i < 1000000; i++) {
  arr.push(Math.floor(Math.random() * 100000000));
  if (i % 10000 === 0) {
      console.log("I", i);
  }
}

console.time("sort");
arr.sort((a, b) => a - b);
console.timeEnd("sort");
```

Now the C++ code:

```cpp
#include <iostream>

#include <vector>

#include <algorithm>

#include <chrono>

extern "C" {

    void sortArray() {

        std::vector<int> arr;

        for (int i = 0; i < 1000000; ++i) {

            arr.push_back(rand());

        }

        auto start = std::chrono::high_resolution_clock::now();

        std::sort(arr.begin(), arr.end());

        auto end = std::chrono::high_resolution_clock::now();

        std::chrono::duration<double> diff = end - start;

        std::cout << "Time to sort in C++: " << diff.count() << " seconds" << std::endl;

    }

}
```

We can compile the above code to a WASM target using emscripten:
``emcc -o sort.js sort.cpp``

Then we get sort.wasm and sort.js files as the Webassembly target code and js code for loading the wasm code using the Browser’s WebAssembly API.

Now when we run sort.js files and the respective sorting code in a browser we can clearly see the time difference in the console:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ndqcygen3c72yby28ir.png)

See the numbers above are much smaller in Javascript and it takes around 0.3 seconds to sort them whereas numbers in CPP are way greater, still it is taked only 0.1 seconds.

Also, this is not the only thing where other languages are faster at, languages like Rust and C++ can also be used in graphics and video processing as well. One great example for this use case is “The Figma’s implementation of WebAssembly on their WebApplication” where they were able to achieve 10X faster loading times using C++ on their canvas editor.

> Also, WebAssembly is never going to replace Javascript, they both go hand in hand, WebAssembly can be leveraged for complex operations whereas for DOM operations Javascript will always be good at atleast in the upcoming years.

So, this was my learning for this week. See you the next week. Do like and share this post with friends and colleagues :)

Keep learning and have a great day 🙋‍♂️