「第3回 Apacheのアクセス・ログを解析する*1」という記事の8ページに「XSの利用方法」という面白い記事があった。XSを利用すると、C言語の関数を利用することができるそうですが、Prime_xsの作成手順が概略だけしか示してなかったので、自分で作成してみました。
以下のページを参考が参考になりました。
http://www.rainylain.jp/vc/perl_module.htm
- h2xsコマンドでモジュールの雛型を作る。
$ h2xs -A -n Prime_xs
- 生成されたXSファイルに専用の記述を含めてCコードを追記する。
Prime_xs.xsファイルを以下のようにしました。
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" long isprime(long lObj) { long j; for( j=2; j*j <= lObj ; ++j ) if( lObj%j == 0 ) return 0; /* not prime */ return 1; /* prime */ } MODULE = Prime_xs PACKAGE = Prime_xs long prime(lLmtCnt) long lLmtCnt CODE: { long lCnt=0, lObj; for(lObj=2; lCnt<lLmtCnt; ++lObj) { lCnt+=isprime(lObj); } RETVAL = lObj - 1; } OUTPUT: RETVAL
- Makefileを生成する。
- makeする。
- 実行
Benchmarkを使って、C言語版、Perl版、Perl+XS版の実効速度を測定しました。
以下は、Bench.plです。
#!/usr/bin/perl -w use strict; use Benchmark; timethese(200, { 'C-Src :' => "system('./Prime 2000 > /dev/null')", 'Perl :' => "system('./Prime.pl 2000 > /dev/null')", 'Perl-XS:' => "system('(cd Prime_xs; ./PrimeXs.pl 2000 > /dev/null)')", });
実行結果は、以下のようになりました。
mmasa@debian:~/work/perl/Prime$ perl Bench.pl Benchmark: timing 200 iterations of C-Src :, Perl :, Perl-XS:... C-Src :: 2 wallclock secs ( 0.00 usr 0.06 sys + 0.14 cusr 1.09 csys = 1.29 CPU) @ 3333.33/s (n=200) Perl :: 17 wallclock secs ( 0.00 usr 0.04 sys + 14.90 cusr 1.69 csys = 16.63 CPU) @ 5000.00/s (n=200) Perl-XS:: 5 wallclock secs ( 0.00 usr 0.04 sys + 0.79 cusr 4.20 csys = 5.03 CPU) @ 5000.00/s (n=200)