高速なCommon LispのWebサーバ「Woo」を作りました

高速なCommon LispのWebサーバ「Woo」を作りました

ここ一ヶ月ほど手掛けていたCommon LispのWebサーバ「Woo」が一応の完成に至りましたのでお知らせします。Clack-compatibleなAPIになっており、現状運用しているClackのWebアプリケーションでそのままお試しいただけます。

高速であることを最優先に設計しており、Hunchentootの4倍、Wookieの3.5倍高速に動きます。現状ではCommon Lispのサーバでは最速ではないでしょうか。*1

Benchmarks

いくつかのCommon Lispのサーバと、Node.js、Go、Pythonのサーバを比較してみました。縦軸はreq/secで、高いほうが多くのリクエストを捌けることを意味します。

f:id:nitro_idiot:20141219152449p:plain

Wooは、PythonのTornadoより約9.5倍、Node.jsの約1.9倍のリクエストを捌けます。一方、Goには少し負けています。

この結果を以ってNode.js遅すぎとか言うつもりは全くなくて、むしろNode.jsがRubyPythonと比べて2倍以上の差をつけているのは純粋に驚きました。Node.jsが速いと言われるのもわかります。

複数CPUコアを有効に使えるように、Workerプロセス数を指定したベンチマークも取りました。

f:id:nitro_idiot:20141219153408p:plain

こちらではRubyUnicornをnginxの裏に置いて試してみました。WooはUnicornの約2.4倍以上のパフォーマンスが出ています。Goよりはさらに差がつけられてしまっていますね。子プロセスへのディスパッチをまともにやらなければ。

ベンチマーク方法などの詳細はWooのリポジトリのBenchmarkをご覧ください。

Installation

インストールには以下のものが必要です。

その後、GitHubからWooをcloneしてbenchmark/woo.lispを実行するとサーバが立ち上がります。

$ mkdir -p ~/common-lisp && cd ~/common-lisp $ git clone github.com/fukamachi/woo $ sbcl --load woo/benchmark/woo.lisp

Why so fast?

WooがHunchentootやWookieに比べて圧倒的な差をつけているのはなぜ?と聞かれます。

最も大きいのは、non-blockingなサーバであり、さらにWookieと違って裏側でlibevを使っていることが大きいです。これで1.5倍くらいは違いますね。 *2

その他はアプリケーションレベルのボトルネックを丁寧に一つ一つ取り除いていきました。

おわりに

WooはGitHubにて公開されています。フィードバックをお待ちしています。

また、Wooは雇い主であるサムライト株式会社の全面的な協力を得て完成を迎えました。現在サムライトではCommon Lisperを募集しておりますので興味がある方は以下のWantedlyからご応募ください。

*1:高速なものとしてteepeedee2が有名ですが、CFFIのAPI変更に追随しておらず動かないようです。同僚が修正を加えた上でLinuxで試したところ、Node.jsより少し速い程度だった、と言っていたのでたぶんWooのほうが速いんじゃないかな

*2:ベンチマーク時のWookieはlibevent2を使っており、現状はlibuvに移行しています。どちらもlibevよりオーバーヘッドが大きく遅い。