Benchmarking a dynamic language (Javascript) against a Strictly typed language (F#/Fable) — Both for the web.

In order to write good and secure dynamic code, you often need to write down guard functions before checking something in order to prevent runtime errors.

In a static language, you need a lot less of those, so I wanted to benchmark and see how much of a difference you get in term of performance by choosing to use a strictly typed language.

Let’s test a simple Javascript function and compare its performance

For the purpose of the test, I have written a simple function that generates employee objects, insert them into an array and then add up the age of all employee to finally determine the average age. I had to write a couple of guards in my Javascript to ensure whoever calls my function must call it properly (and prevent runtime crash).

In order to properly test and see how well this code runs, there is a test bench included in the code to gather timing data for couple use cases. We will do the same testing for the same functions written with F# as well.

Let’s test the same function written in F# and transpiled to Javascript and run the same set of performance test on the generated code.

For this use case, I have decided to use F# with Fable (It’s a compiler that transpile F# code to Javascript code). You will find the same adapted code below.

Since F# is a statically typed language, we don’t have the same need of guard functions due to the compiler and our types protecting us from some of those issues.

The code we will use to run our tests

The final results

In order to properly benchmark my tests, I have run three different tests

Fable with F# compiled to Javascript The guarded Javascript version of the code shown above The unguarded Javascript version of the code shown above

I have run all the three different test on the same hardware 10 times to gather data and build up a graphic. The graphic shows the average time it took to execute each function on my hardware.

I have dropped the Test #1 and Test #2 from the graphic because the difference was too little to be of use.

You will notice that Fable and the Unguarded Javascript version of the test both perform on very similar performance level on the 1 million tests, but a significant difference for the guarded Javascript one (an increase of around 100ms).

For the 10 million tests, you will notice that Fable eventually as well drop a little bit in performance compared to the UNGUARDED Javascript version, but is still up by a marginal difference compared to the GUARDED version of the test (~600ms).

Following normal development pattern, you will usually build single-responsibility components guarded because you build re-usable components that will be used in multiple contexts for which you want to properly handle errors and ensure it is working properly.

Unfortunately, in Javascript, you have no other choice to write actual runtime executed code to validate those entries, which turns out to be costly down the line, but if you think you are above all else and can write unguarded Javascript code, then you will get slightly better performance out of it (Since Fable has some imported libraries used for certain data manipulation).

In term of a normal comparison (guarded vs guarded), we can see here that for the security you get from a strictly typed language, you gain a considerable amount of performance compared to writing guard functions all over the place in your code.

We have run a pretty simple setup here, imagine the impact this actually have on a much larger application that does things a lot more complicated than this.

Because we have less guarding code to write, static languages boast better performance (at least for the ones that transpiles to Javascript on the web) and that eventually, that comes to play a role in the experience the user has with your application.