DEV Community

Pouya Eghbali
Pouya Eghbali

Posted on

Clio: extremely fast, multi-threaded code on the browser

Clio lets you run multi-threaded code on the browser

Clio is a functional programming language that compiles to JavaScript. It runs on Node.js as well as in the browser and is multi-threaded on both. Clio makes it super easy to do parallel or distributed programming, you can easily use the CPU cores on the local device, or use the resources on another device available on the network. Clio scales indefinitely. It has a clean syntax and is super fast. You can read an introduction to Clio here on medium, visit our GitHub repository or website, or you can directly go on to our playground to see and try a few examples.

Let me, however, show you a quick demonstration of Clio, and how to do multi-threading with it. To do multi-threading on the browser or on Node.js, all you need to do is to define your functions and call them using the |sandwich| syntax, Clio takes care of the rest:

Fib function written in Clio

If you want to, you can run this example directly on the playground.

In this example, there are a few little details that need explanation. On line 8 of the sample code above, you can see a demonstration of the Clio sandwich syntax |fib|, which runs the fib function in a separate thread. On the same line, you can see that -> * is used for mapping the data to the|fib|function. On line 9, (console.log @it) is an anonymous function that accepts it as its first parameter.

With Clio, it is also possible to import functions over the network and use them like any other regular function. Instead of making and implementing API endpoints, with Clio you can just host your functions and import them elsewhere, Clio gives you FaaS and micro-services architecture for free, without any extra hassle. For example

Clio remote functions

is valid Clio code. To see a demonstration of the remote functions, you can check out our todo example here.

The Clio v0.11.0 release, which just got recently published brings a couple of important changes. These changes are mostly performance-related: they improve the execution speed of Clio code, as well as improving the overall RPC and multi-threading performance. In this article, I’ll be showing you how fast Clio really is, and we will go through these new enhancements together. Let’s start with the performance!

How fast is Clio?

Since Clio compiles to JavaScript, everyone’s first assumption is that Clio is slower, or as slow as JavaScript. That might be true for a language like TypeScript, but Clio is actually faster than JavaScript, and in certain situations, it is extremely faster than JavaScript. I will explain how Clio can achieve such a performance later on in the article. But for now, let’s take a look at how fast we are talking about.

Fib(1000) best of 10k

The above chart shows execution times for calculating the 1000th Fibonacci number in different programming languages. As you can see, Clio is almost as fast as C. Of course, I do not expect Clio to be this fast always or in every other situation, and I do not claim that Clio is as fast as C, what I claim is that Clio is super fast, and a lot of work has been done in making it fast. So how can it be so fast if it compiles to JavaScript?

First of all, I should mention that JavaScript, contradictory to the common belief, is actually a very fast programming language. Since Clio *compiles *to JavaScript, the compiler can apply compile-time optimizations to the generated JavaScript. In the case of the above example, tail call optimization is applied to the Fibonacci function. You can find the source code for the benchmark here.

Another reason why Clio runs faster than JavaScript is the way Clio code is written: using pipes, one can avoid creating intermediate constants or variables. The output of a function call can be directly piped to another function, and from there to another. Of course, it is also possible to nest function calls in JavaScript and avoid making intermediate variables, however, the Clio syntax was carefully designed to allow doing this while maintaining the readability. For example, the following JavaScript code:

JavaScript

Becomes this in Clio:

Clio

In the JavaScript example above, the order of execution of the functions is from the inside to the outside, but in the Clio code, it gets executed from left to right, in the exact same order you read and write the code. This makes a lot more sense if you think about it!

A lot of time and effort was spent on keeping Clio fast, and we had to sacrifice quite a few features along the way for that. As an example, we had to give up on laziness, because the V8 engine we run on doesn’t support it natively. However, we made sure that Clio compatible stays with JavaScript.

As a result of that, you can now import any JavaScript library into Clio and use it without facing any issues. As a result, you can even benefit from the multi-threading features of Clio to make your JavaScript libraries run faster:

Clio parallel performance

In the above chart, you can see how parallelizing your tasks with Clio improves their performance! As an example, Jimp, a pure JavaScript image manipulation library was used to apply a greyscale effect to a directory full of images. With Clio, you can apply the effect to each image in a separate thread, which greatly improves performance. In Clio version v0.11.0 a lot of work was done to make parallelism even faster, more efficient and much better than ever before!

Parallelism in Clio

Clio has a network-based parallelism model. You can call it a distributed computing model. On startup, Clio creates a central hub or message broker, called a dispatcher, and listens to connections on different protocols based on the project’s configuration. Then it spawns workers and waits for them to connect to the dispatcher. A dispatcher is just a message hub or a broker that relays messages between the main thread and the workers. There is no shared memory between the workers and the main thread, so Clio has to serialize each and every message.

Prior to version v0.11.0, Clio used JSON for serialization. JSON is available everywhere and it’s fairly fast, so at first, it might sound like a good idea to go with JSON. Unfortunately, as soon as we start serializing custom types with JSON, its performance degrades to the point that it’s not efficient anymore. To solve this issue, I created a serialization library for JavaScript named Sia, and to boost its serialization performance to the next level, I also designed a new text encoding which I called utfz. I spent over a year optimizing these two libraries, and as a result, managed to make Sia so fast that the pure JavaScript version of it beats even the performance of the native serialization libraries available for Node.js!

Serializing custom data types

Sia is a binary serialization format, and as you can see in the above chart, Sia is extremely fast! To see more benchmarks, or to learn more about Sia and how it was made so fast, you can refer to this medium article. Using Sia as a serialization library, Clio gained a big performance boost on multi-threading, its remote function calls and RPC protocol.

Clio RPC threading performance

The above chart shows the performance gain of Clio after I made the switch to Sia. Not only it’s faster to serialize the data, it is now also faster to transfer the data. With Sia, the serialized data is much smaller than JSON and is already in binary format! On the browser also, the performance is greatly improved. For a quick demo, you can check the video below on how faster the Clio Mandelbrot example renders on Sia in comparison to JSON:

This video shows the render time for a multi-threaded Mandelbrot example written in Clio. You can check it in action here, or you can check the source code on GitHub. As you can see, the Sia version is much faster than the JSON version, and finishes almost in half the time as the JSON one!

With Clio, it’s super easy to run functions in a thread, no need to set up anything yourself, no dealing with the web workers or the worker threads, no need to implement communication protocols or synchronization, everything is already taken care of, just run clio new to scaffold a new project, write your code, then run the clio run command and you’ll get your app up and running in just a few seconds. You can check examples on the Clio examples repository.

Clio is still a very young language and it has a long way to go, it is not production-ready yet, and I’m not rushing for a stable release. I want to keep it minimal, and I want to carefully choose what goes in or what we should keep out of the language. It is designed with the cloud and micro-services in mind, and that’s where the main focus is. With Clio, I’m aiming for a general-purpose language that is usable both on and off the web, a language that is suitable for making a website, as well as crunching numbers and scientific data.

If you have any questions, leave a comment under this article, post an issue on GitHub, and if you want to talk, you’re welcome to join our public chat on Telegram!

GitHub logo clio-lang / clio

Clio is a functional, parallel, distributed programming language.

npm version Travis (.org) Documentation Status Codacy Badge codecov Telegram Share on Twitter

Clio Logo

Clio

Clio is a functional, distributed programming language that compiles to JavaScript. It runs in the browser and on the server and is made to be a suitable language for scientific programming. Clio takes advantage of multiple CPUs and multiple CPU cores (parallelism) by default, is able to use network resources, is easy to run on clusters and on the cloud.

Read Clio documentation or visit our website for more info.

Clio Logo

Install

To install you'll need Node.js (latest version) and NPM. Clio is hosted on NPM, to install it simply do

npm i -g clio
Enter fullscreen mode Exit fullscreen mode

Command Line Usage

To see a list of available clio commands and their description you can run

clio --help
Enter fullscreen mode Exit fullscreen mode

Project Status

Clio is in active development and it's not ready for production It is in a highly experimental state, although some stable demonstrations and test programs exist, it is not recommended to use in production.

Discussion (0)