php swigでフィボナッチしてみた

PHPはスクリプト言語なので、書いたらすぐ実行できますが、そのつど逐次解釈しながら実行されるので、あまりパフォーマンスを要求される処理には向かないなどと言われます。
そうは言っても、PHPで重い処理を書かないとならないこともあるでしょう。そんなときにも、こなれたPHPでパフォーマンスを確保しつつコーディングすることができれば、将来は今よりもう少し明るいものになるかもしれません。
SWIGはそんなときに使えそうです。売りはどちらかといったら「C/C++のコードをさまざまなスクリプト言語で利用できること」にあるようですが、「C/C++のもつパフォーマンスの恩恵に預かること」もできて、上述のようなケースではとても役に立ちます。
しかもC/C++のコードを組み込むのにPHPのリコンパイルは不要という、使い勝手もとてもいい感じです。
ためしにSWIGのインストールから、フィボナッチ数列の計算式をSWIGで実装し、通常のユーザー定義関数のそれと比べてどの程度差が出るか、はっけよいのこったしてみました。
環境:CentOS 5.3、 PHP 5.3.1
さっそくまずはSWIGのインストール

$ cd /usr/local/src/
$ wget "http://sourceforge.net/projects/swig/files/swig/swig-2.0.4/swig-2.0.4.tar.gz/download"
$ tar zxvf swig-2.0.4.tar.gz
$ cd swig-2.0.4
$ ./configure
$ make
$ sudo make install
$ which swig
/usr/local/bin/swig
$ cd ~/

簡単です。
次に、Cでフィボナッチ

$ vim fibo.i
/* fibo.i */
%module Fibonacci
%{
unsigned long calc(int n);
%}
unsigned long calc(int n);
$ vim fibo.c
/* calc.c */
unsigned long calc(int n) {
unsigned long f;
switch (n) {
case 1:
case 2:
f = 1L;
break;
default:
f = calc(n - 1) + calc(n - 2);
break;
}
return (f);
}

で、フィボナッチをPHPに組み込む

$ swig -php fibo.i
$ cc -fpic -c fibo.c
$ gcc `php-config --includes` -fpic -c fibo_wrap.c
$ gcc -shared *.o -o fibo.so
$ sudo cp fibo.so `php-config --extension-dir`
$ echo 'extension=fibo.so' >> /etc/php.ini

これで完了です。
実行する前に、比較用に普通のPHPも書いておきます。
PHPでフィボナッチ

$ vim fib.php

では比べてみましょう。40番目のフィボナッチ数を求めてみます。
まず普通のPHPから

$ time php -r 'require "fib.php";
> for($i=1; $i<=40; $i++) {
>   var_dump(fibonacci($i));
> }'
...
int(102334155)
real    5m52.546s
user    5m52.369s
sys     0m0.107s

6分弱かかりました。
次にSWIGで組み込んだ方

$ time php -r 'require "fibonacci.php";
> for($i=1; $i<=40; $i++) {
>   var_dump(Fibonacci::calc($i));
> }'
...
int(102334155)
real    0m5.444s
user    0m5.434s
sys     0m0.010s

6秒弱でした。
なんと実に約65倍のパフォーマンス。想像以上の速さです。KVSとか全文検索とかとの連携やバッチなどで、ここぞというときには積極的に使ってみたいですね。
ref)
SWIG
SWIG を使って PHP 拡張機能を作成する

フィボナッチ数でベンチマーク(サーバーサイド言語)

C言語講座:フィボナッチ数列