Benchmarking REST daemons/minimal web servers

3 min read Original article ↗

As always, I've got to bring in one of my personal favorite languages (Common Lisp) and see how it performs in the context of these other languages.

Pop open a Common Lisp REPL (I assume you have a working copy of SBCL and Quicklisp set up, otherwise go do that first) and type:

(ql:quickload :woo)
(woo:run (lambda (env) (declare (ignore env)) '(200 (:content-type "text/plain") ("Hello, World"))))

Voila, a working web server to serve "Hello, World" requiring nothing more than 10 seconds of time in the Common Lisp REPL.

Lets see how it performs with the following:

ab -c10 -n1000  'http://127.0.0.1:5000'

and we see the output:

Concurrency Level:      10
Time taken for tests:   0.332 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      114000 bytes
HTML transferred:       12000 bytes
Requests per second:    3015.20 [#/sec] (mean)
Time per request:       3.317 [ms] (mean)
Time per request:       0.332 [ms] (mean, across all concurrent requests)
Transfer rate:          335.68 [Kbytes/sec] received

Wow! Finally broke the 3000/RPS mark on this old rig.

To his credit, the author of this package is amazing, and I suggest you check out his Github for it (scroll down a little to see how it compares to other language servers):

https://github.com/fukamachi/woo

On a good machine, such as the one he benches on, he hits 40,000/RPS (with the next highest being a server written in Go reaching 30,000).

Is Common Lisp faster than C++? Not necessarily in every context, but if you look at general language benchmarks, it actually does surpass C++ and Java in some (and get beat in others), leaving only pure minimal C as a language that can consistently come in at number one, so, lets go find and test out a C based web server that can serve minimal responses.

Lets try some Common Lisp with an actual framework (Caveman2 in this case, using the bare skeleton produced by the following):

(ql:quickload :caveman2)
(caveman2:make-project (pathname "~/src/lisp/cm2-bench"))
(cm2-bench:start :server :woo :port 5000)
Concurrency Level:      10
Time taken for tests:   1.166 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      307000 bytes
HTML transferred:       12000 bytes
Requests per second:    857.86 [#/sec] (mean)
Time per request:       11.657 [ms] (mean)
Time per request:       1.166 [ms] (mean, across all concurrent requests)
Transfer rate:          257.19 [Kbytes/sec] received

Hmm, alright, so it seems inline with the speed of node + express - definitely not as nice as the plain woo bench of a simple request, but still decent.