Dummy web benchmark with nim, zig, go, bun, node, python
Last week Daniel Lemire published a simple hello world web benchmark in multiple languages.
There were a couple of things that picked my interest:
- bun.sh was supposed to be faster (the initial post was using bun+fastify, which was not optimal)
- nim ranking was certainly a surprise as well (Nim is a language that resembles python but is natively compiled).
Some of the toy experiments from Lemire’s blog were slightly biased in the original post, since some of the toy web servers were returning “hello world” and some others “hello”, plus some had some sort of routing, while others did not. Overal performance was similar, but I thought it was a good idea to update all tests locally to return the exact same string and use same exact routing to keep the same spirit on all the servers. Lemire later updated his blog with more languages.
Last week, when I read the article I downloaded the source code from Lemire’s blog and did some local changes and experiments to play around. Here are my results with different languages / frameworks after updating slightly the test and including some more:
|nim||182k rpm||29.30MB/s||nim 2.0.0|
|nim||168k rpm||27.00MB/s||nim 1.4.0|
|zig+zap||159k rpm||32.70MB/s||zig 0.11 - ReleaseFast|
|go+fiber||142k rpm||26.69MB/s||go 1.18.1 + fiber v2|
|go+fiber||137k rpm||24.93MB/s||go 1.21.2 + fiber v2|
|go||113k rpm||20.50MB/s||go 1.18.1|
|go||105k rpm||19.16MB/s||go 1.21.2|
|bun (native)||74.5k rpm||13.44MB/s||bun 1.0.3|
|node (native)||32k rpm||7.22MB/s||node v20.8.0|
|bun+fastify||27k rpm||4.86MB/s||bun 1.0.3|
|python+fastapi||8k rpm||1.68MB/s||python 3.10.12|
I used same command Lemire was using on his initial post:
$ bombardier -c 10 http://localhost:3000/simple
Here is the computer I used:
- CPU: Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
- RAM: 32GB
I added Python just to compare, and although I was expecting it to be slower than other frameworks, I thought it would be faster that what I got. It was kind of a disappointment.
These results are orientative, but give a good sense on how different languages/frameworks are preforming high-level. Feel free to take these results with a grain of salt, though.
Anyway, usually real-world performance depends on lots of other factors (IO, database, network conditions, …).
In the ideal world I should be providing the source code, environment, etc…but hey, I just did this to play around. If you want, you can find some source code on Lemire’s post to get started. Either way, if you feel courious, I would encourage you to run your own experiments.
I remember it was an interesting read at the time.