2009/04/07

XSを使ってみる

PerlからC APIを呼ぶ仕組みでXSというものがあります。
これにより、Cで書いた部分の処理に関しては高速になったり、既存のCで書かれたライブラリが使用できるようになるらしいです。
ちょっとおもしろそうなので、練習に動かしてみました。

モダンPerl入門に詳しく書いてあったのですが、ちょっとやることが多すぎたので下記のサイトの例をやってみました。
http://d.hatena.ne.jp/higepon/20050615/1118829090

手順は上記のサイトに書いてある通りに行いました。
$ h2xs -A -n MyTestXS ←XSのひな形を作成
$ cd MyTestXS/
$ perl Makefile.PL ← Makefileを作成
[MyTestXS.xsを編集]
$ make


MyTestXS.xsは次のように編集しました。
ちなみにMODULE = MyTestXSまでは自動的に作成されてました。
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"


MODULE = MyTestXS PACKAGE = MyTestXS

int
increment2(value)
int value
CODE:
RETVAL = value + 2;
OUTPUT:
RETVAL

追記した部分は、まず戻り値の型、関数名、引数名と型を指定します。
CODEより後ろには実際のCのコードを記述します。
OUTPUTに戻り値を指定します。

makeして失敗がなければ、XSモジュール作成完了です。
では、実際に使ってみつつ、ベンチマークもやってみました。
下記のようなコードを書きました。これも参考サイトと同じです。
#!/usr/bin/perl
use strict;

use ExtUtils::testlib;
use MyTestXS;

use Benchmark;

my $count = 5000000;
timethese($count,
{
'XS' => 'xs_test();',
'Perl' => 'perl_test();',
});

sub xs_test {
MyTestXS::increment2(100);
}

sub perl_test {
increment2(100);
}

sub increment2 {
$_[0] + 2;
}

これを実際に私のMacBookで実行してみると下記のような結果になりました。
macbook:MyTestXS hiroki$ perl ./test.pl 
Benchmark: timing 5000000 iterations of Perl, XS...
Perl: 5 wallclock secs ( 5.95 usr + 0.08 sys = 6.03 CPU) @ 829187.40/s (n=5000000)
XS: 3 wallclock secs ( 3.46 usr + 0.04 sys = 3.50 CPU) @ 1428571.43/s (n=5000000)

XSで書いた方が2倍近くパフォーマンスが良いです。

私としては、はやく動かすというよりも既存のCライブラリをPerlから使いたいと思ってるので、引き続き調べます。
モダンPerl入門を見ると詳細に書いてあるようで。

0 件のコメント: