'(you lisp me)

Lispって何だ

フィボナッチでのベンチマーク'(C CCL SBCL)

正直ベンチマーク記事は(世に溢れてるから)あまり書きたくなかったのですが,少しびっくりしたことがあったので書きます.

ベンチを取るに至った経緯

先日,某SNSで知り合った方とSkypeでお話する機会がありました.内容の殆どがプログラミングの話題で,互いのやりたいことについて語りました.非常に楽しかったですし,自分とは違う所を目指している人との話は新鮮でした.その中で出た話題の一つに,一番パフォーマンスの良い言語は何かということがありました.彼は,一番速いのは結局のところ最適化をかけたCだろうと言っていました.確かにその考えは現実的であり,もっともであると思いました.しかし僕はLispに夢を抱いてしまったがため,多少劣ろうがLispも負けてはいないというところを証明したかったのです.

結果

さて,それでは実際に結果をお見せしましょうか.以下がベンチマークの結果になります(測定はtimeコマンド).
僕が今回驚いたのは,Clozure CLがSBCLの速度を上回っていることです!

追記(2015/10/18 15:20):
redditの方でご指摘があったので,CLの方の戻り値の型指定と最適化オプションを追加してみました.
また,10回計測して最も速いタイムを記載するようにしました.
依然としてClozure CLの方が速いようですが,SBCLもCの1/2倍を切りました!

gcc -O2(5.2.0) time
real 0m0.201s
user 0m0.200s
sys 0m0.000s
ccl(1.11) time
real 0m0.340s
user 0m0.333s
sys 0m0.007s
sbcl(1.2.12) time
real 0m0.362s
user 0m0.360s
sys 0m0.000s

ベンチマークコードが以下になります.

CLのコードはsbclでもcclでも同じコードから実行ファイルが生成出来るように,実行ファイル生成部分をまとめてみました.今回の結果を比較してみると,型指定などの最適化を施すとCommon LispでもCの1/2倍程度の速度が出ることが分かります.他の言語とも比較してみないと詳しいことは分かりませんが,上出来でしょう.

結果的にはCLの負けですが,例えば以下のようなコードだとどうでしょうか.

これの測定結果が以下になります(cclもほとんど同じ結果).

sbcl time
real 0m0.006s
user 0m0.003s
sys 0m0.000s

このコードでは150番目のフィボナッチ数を求めています.先ほどの'よくあるフィボナッチ数を求めるコードで150番目の数を求めようとすると,非常に長い時間がかかります(なので僕は求まる前にC-cしてしまいました).このように同じ結果を求める場合でも,書き方によっては非常に速くなる場合があります.
追記(2015/10/23 11:44):
そもそもこれなら末尾最適化した方が速いですね(笑)

同じことをCでやればより速いタイムで上回って来るとは思いますが,僕が思うにこれがLispでCに(速度で)勝つ方法なのではないでしょうか.