読者です 読者をやめる 読者になる 読者になる

Mae向きなブログ

Mae向きな日記のブログ版。ようやくこちらに移行してきました。

XS

「第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)