たらい回し関数の速度比較
aviutl拡張編集がLuaを使っているから、というだけで何となくLuaに手を出してみた。意外と簡単だし、実行速度も速いと感じたので、xyzzy lispと比較してみる。
せっかくなので、c++とも比較してみたいと思い、ベンチマーク用に適当なたらい回し関数を利用する。
; lisp (defun tak (x y z) (if (< y x) (tak (tak (1- x) y z) (tak (1- y) z x) (tak (1- z) x y)) z))
-- lua function tak (x, y, z) if y < x then return tak(tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y)) else return z end end
// c++ int tak(int x, int y, int z) { if (y<x) return tak(tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y)); else return z; }
三者とも書き方が微妙に違う。いやらしい。
これらについて、適当に(tak 18 9 0)を実行するメイン関数を書いて、xyzzyから呼び出し、結果が返ってくる時間を10回測定し、平均を取った。外部呼び出しのluaとc++は呼び出しコストが大きいので、何もしないプログラムを呼び出す時間を差し引いた。
処理系 | 時間(ms) | xyzzy比 | gcc比 |
---|---|---|---|
xyzzy 0.2.2.236 | 33470 | 1000 | 293.6 |
Lua 5.1.4 | 3139 | 94 | 27.54 |
LuaJIT 1.1.7 | 756 | 23 | 6.632 |
gcc (tdm-1) 4.5.0 (-O2) | 114 | 3 | 1.000 |
xyzzyと比較するとLuaは11倍速い。差がありすぎる。LuaJITの方が速いらしいので、これも比較したら、さらに4倍くらい速い。c++と比較すると、LuaJITでも6.6倍くらい遅いのだが、スクリプト言語としては相当速いだろう。xyzzyはc++に対して300倍近く遅い・・・。
もっとも、これは主に関数呼び出しの速度を計測するベンチマークである。c++でメモリ管理をしっかり行い、ハッシュテーブル等を導入すれば処理は遅くなる。また、スクリプト側もc++のライブラリ関数を使えば、その分だけc++との差が小さくなる。そう考えると、LuaJITでは、少ない労力でc++に近いパフォーマンスが期待できるのではないだろうか。