LispをCより速くする

ときどきの雑記帖経由で知った
How to make Lisp go faster than C
という論文が面白いです。
簡単な画像処理をCとCommon Lispで書いて速度を比べるというものですが、
CLの速度の劇的な変化が笑えます。
インタプリタで実行 -> Cの2300倍遅い
コンパイルして実行 -> Cの60倍遅い
型宣言と最適化を付ける -> Cと同等の速度(一部に関してはCより速い)
いくらなんでも最初より速くなりすぎだろwwww
おまけに、最初のソースと最終的なソースの差はほとんど無く、
関数一つあたり、2,3行増える程度です。これは凄い。
あと、CMUCLの型推論がACLより優秀という話も面白かったです。

(defun mult (to from val)
(declare (type (simple-array fixnum (*))
to from))
(declare (type fixnum val))
(let ((size (array-dimension to 0)))
(dotimes (i size)
(setf (aref to i) (* (aref from i) val)))))

配列fromの要素とvalの積はfixnumの範囲を超える可能性があるため、
ACLでは何も指定しない限り(*1)genericな乗算が行われるけど(*2)
CMUCLでは格納先のtoの要素の型がfixnumであるため、
fixnum用の乗算(つまりCPUのnativeな乗算命令)が行われるそうです。
手元のSBCLで試したところ、確かにIMULになってました。
(*1) 同様の命令を吐かせたければ (the fixnum (* (aref from i) val)) とすればいいそうです。
(*2) 2006年の論文なので現在のACLではどうか分かりません。

CやCLやSchemeの様にしっかりと仕様が定められている言語は、
色んなところが処理系を作って互いに競い合うため、
どんどんいいものが生まれていくのがいいですね。

Leave a Reply