Hatena::ブログ(Diary)

makogの日記 RSSフィード

2009-12-11

[][] Cache::FileCache の purge と Purge

Cache::FileCache を使っていて、期限切れキャッシュのファイルが削除されなくてはまりました。

この記事 を参考にして Purge() していたのですが、どうやら Cache::FileCache には purge と Purge があるようなのです。上の記事のコメントを見て知りました。

で、この二つはどう違うのか、ソースをざっくりと見てみたのですが、

Purge() は、呼び出し元のオブジェクトの指定に関わりなく、引数に指定したディレクトリ以下のすべてのファイルについて、期限切れファイルを削除するようです。なので、$cache->Purge( '/path/to/cache_root' ); あるいは、Cache::FileCache::Purge( '/path/to/cache_root' ); という風に実行する必要があるのですね。

purge() は、呼び出し元のオブジェクトに指定したディレクトリ・namespace の期限切れファイルを削除してくれます。

ので、上の記事ではやはり、purge() を使うのが正しそうですね。

それにしても、このインタフェースはどうかと思いますね・・・。Cache::CacheのPOD にある説明もどうかと・・・。

2009-07-05

[][] Text::MicroTemplate と Template-Toolkit のベンチマーク

Perlの軽量フレームワークMENTANanoA)から生まれた Text::MicroTemplateと、ご存じ Template-Toolkit の比較のため、ベンチマークしてみました。参考までに、こちらも有名どころの HTML::Template も入れてみました。


結果

Benchmark: timing 5000 iterations of HTML::Template, Template-Toolkit, Text::MicroTemplate...
HTML::Template:  2 wallclock secs ( 1.68 usr +  0.04 sys =  1.72 CPU) @ 2906.98/s (n=5000)
Template-Toolkit:  9 wallclock secs ( 8.73 usr +  0.36 sys =  9.09 CPU) @ 550.06/s (n=5000)
Text::MicroTemplate: 10 wallclock secs ( 8.83 usr +  0.44 sys =  9.27 CPU) @ 539.37/s (n=5000)
                      Rate Text::MicroTemplate Template-Toolkit   HTML::Template
Text::MicroTemplate  539/s                  --              -2%             -81%
Template-Toolkit     550/s                  2%               --             -81%
HTML::Template      2907/s                439%             428%               --

Mac OS X 10.5、Perl 5.8.8 にて。実際の使用にあわせて、キャッシュ有り、UTF-8フラグを立てる仕様で、単純なテンプレート処理を計っています(コードは下記)。ちなみに、Text::MicroTemplate Ver 0.05、Template-Toolkit Ver 2.21、HTML::Template Ver 2.9 を使用。

HTML::Template は低機能なだけあって速いですね。Text::MicroTemplate と Template-Toolkit は、いずれもPerlで実行できるソースコードを作り出してからそれを eval する仕組みなので、eval のコストがほとんどになってしまうようです。

それじゃあキャッシュさせなかったらどうよ、というベンチマークの結果は以下。キャッシュさせないように、テンプレートの内容を予め読み込んでおいて scalar_ref で渡すようにしています。

Benchmark: timing 5000 iterations of HTML::Template, Template-Toolkit, Text::MicroTemplate...
HTML::Template:  5 wallclock secs ( 5.34 usr +  0.01 sys =  5.35 CPU) @ 934.58/s (n=5000)
Template-Toolkit: 19 wallclock secs (19.17 usr +  0.05 sys = 19.22 CPU) @ 260.15/s (n=5000)
Text::MicroTemplate:  9 wallclock secs ( 9.06 usr +  0.04 sys =  9.10 CPU) @ 549.45/s (n=5000)
                     Rate Template-Toolkit Text::MicroTemplate    HTML::Template
Template-Toolkit    260/s               --                -53%              -72%
Text::MicroTemplate 549/s             111%                  --              -41%
HTML::Template      935/s             259%                 70%                --

最近の軽量フレームワーク

私の仕事としては、Perlモジュールが自由にインストールできない、ホスティングだったり管理者がうるさい自社サーバで使うものが多いので、最近の軽量フレームワークMojoなどはとてもありがたい存在です。ソースコードを読んで自分の業務にあった軽量フレームワークを作ったりして勉強しています。

Mojo::Template は今回の比較には入れませんでしたが、Text::MicroTemplate はこれをベースにしているので、同じような結果がでるのではないか、と思っています。

PHPでは、同じような理由で CakePHP を使ったりもしています。

こういったニーズって結構あるんじゃないかなぁと思っているのですが、Perlではなかなかメジャーな、PurePerl(コアモジュール含む)なフレームワークって無かったですよね。今回ベンチマークしたモジュールは、全て「.pm」ファイルを置くだけで実行できるPurePerlなテンプレートエンジンです。MENTANanoA の作者の方々に感謝しつつ、もっとこの流れが発展することを願っております。


ベンチマークのソース

use strict;
use warnings;
use utf8;
use Encode;
use Benchmark qw( timethese cmpthese );

use Text::MicroTemplate::File;
use Template;
use Template::Provider::Encoding;
use Template::Stash::ForceUTF8;
use HTML::Template;

my $times = shift @ARGV || 1000;

my $data = {
  items => [
    {
      id   => 'aaa',
      name => 'あいうえおかきくけこ',
      desc => '説明文1です。説明文1です。',
      stat => 0,
    },
    {
      id   => 'bbb',
      name => 'さしすせそたちつてと',
      desc => '説明文2です。説明文2です。',
      stat => 1,
    },
    {
      id   => 'ccc',
      name => 'なにぬねのはひふへほ',
      desc => '説明文3です。説明文3です。',
      stat => 0,
    },
  ],
  doc_root => '/path/to/document_root/',
};

my $tmpl_tt = './tmpl_tt.html';
my $tmpl_mt = './tmpl_mt.html';
my $tmpl_ht = './tmpl_ht.html';

binmode STDOUT, ':utf8';

my $comp = timethese( $times, {
  'Template-Toolkit'    => \&template_toolkit,
  'Text::MicroTemplate' => \&text_microtemplate,
  'HTML::Template'      => \&html_template,
} );

cmpthese( $comp );

sub template_toolkit {
  my $tmpl = Template->new(
    LOAD_TEMPLATES => [ Template::Provider::Encoding->new(
      RELATIVE => 1,
      COMPILE_DIR    => './cache_tt',
    ) ],
    STASH          => Template::Stash::ForceUTF8->new(),
  );
  my $html = '';
  $tmpl->process( $tmpl_tt, $data, \$html ) or die $tmpl->error();
  return $html;
}

sub text_microtemplate {
  my $tmpl = Text::MicroTemplate::File->new(
    cache => 1,
  );
  my $html = $tmpl->render_file( $tmpl_mt, $data );
  return ${$html};
}

sub html_template {
  my $tmpl = HTML::Template->new(
    filename => $tmpl_ht,
    die_on_bad_params => 0,
    cache => 1,
    filter => sub {
      my $text_ref = shift;
      ${$text_ref} = Encode::decode( 'utf8', ${$text_ref} );
    }
  );
  $tmpl->param( %{$data} );
  return $tmpl->output();
}

そうそう、Template-Toolkit の UTF-8 フラグ立てには、Template::Provider::Encodingを使っています。

2009-04-20

[][] Cache::File と Cache::FileCache の比較

とある仕事でファイルキャッシュを使う機会があったので、似た名前、ほぼ同じ機能の Cache::File と Cache::FileCache をベンチマークしてみました。

導入障壁という意味でも、より依存するPerlモジュールの少ない Cache::FileCache に軍配が上がりました。

ベンチマーク結果

Benchmark: timing 50 iterations of Cache::File (write), Cache::FileCache (write)...
Cache::File (write): 19 wallclock secs ( 4.89 usr + 11.79 sys = 16.68 CPU) @  3.00/s (n=50)
Cache::FileCache (write):  4 wallclock secs ( 1.26 usr +  1.32 sys =  2.58 CPU) @ 19.38/s (n=50)
                           Rate     Cache::File (write) Cache::FileCache (write)
Cache::File (write)      3.00/s                      --                     -85%
Cache::FileCache (write) 19.4/s                    547%                       --
Benchmark: timing 50 iterations of Cache::File (read), Cache::FileCache (read)...
Cache::File (read): 16 wallclock secs ( 4.00 usr + 10.99 sys = 14.99 CPU) @  3.34/s (n=50)
Cache::FileCache (read):  1 wallclock secs ( 0.50 usr +  0.22 sys =  0.72 CPU) @ 69.44/s (n=50)
                          Rate      Cache::File (read) Cache::FileCache (read)
Cache::File (read)      3.34/s                      --                    -95%
Cache::FileCache (read) 69.4/s                   1982%                      --

スクリプト


use strict;
use warnings;
use Benchmark qw( timethese cmpthese );
use Cache::FileCache;
use Cache::File;

my $times = shift @ARGV || 50;
my @chars = ( 'a'..'z' );

my $filecache = Cache::FileCache->new( {
  namespace => 'bench',
  default_expires_in => 6000,
  cache_root => '/tmp',
} );
$filecache->Clear();

my $file = Cache::File->new(
  cache_root => '/tmp/bench',
  default_expires => '6000 sec',
);
$file->clear();


my $comp = timethese( $times, {
  'Cache::FileCache (write)' => sub {
    foreach( @chars ) {
      $filecache->set( $_, $_ x 32 );
    }
  },
  
  'Cache::File (write)' => sub {
    foreach( @chars ) {
      $file->set( $_, $_ x 32 );
    }
  },
} );
cmpthese( $comp );

my $comp2 = timethese( $times, {
  'Cache::FileCache (read)' => sub {
    foreach( @chars ) {
      my $data = $filecache->get( $_ );
    }
  },

  'Cache::File (read)' => sub {
    foreach( @chars ) {
      my $data = $file->get( $_ );
    }
  },
} );
cmpthese( $comp2 );

$filecache->Clear();
$file->clear();

1;
__END__

2007-06-01

[][]Net::Nslookup

Perlモジュール Net::Nslookup をCPAN から Mac OS X Tiger にインストールしようとしたところ、

t/nslookup.....ok 1/2
#   Failed test 'localhost => ::1'
#   at t/nslookup.t line 49.
# Looks like you failed 1 test of 2.

t/nslookup.....dubious
       Test returned status 1 (wstat 256, 0x100)
DIED. FAILED test 2
       Failed 1/2 tests, 50.00% okay

といった具合に、make test でこけてしまいます。

テストケースを見てみると、どうやら /etc/hosts を参照してごにょごにょしているようです。

::1 localhost

/etc/hosts にデフォルトで入っている、上記の設定でこけているようですね(これってどういう意味なんですか?)これらをコメントアウトしたら、make test が通るようになりました。

Net::Nslookup のメンテナーに報告しようかと思いましたが、英語が苦手なのでやめておきます。

2007-05-01

[][] XML関連モジュールのまとめ

仕事でXMLやRSSを処理する機会がありそうなので、XML関連のPerlモジュールを調べていました。

どうやらXML::Simpleは遅いらしいです。コンパイル済みのバイナリである expat(XML::Parser)を使っているはずなのに、なんででしょうね。

正規表現の方が速い理由はなんとなしに分かりますが(その分、汎用性は低くなる訳ですから)、数百倍遅い、とか言われると、ちょっと避けたくなってしまいますよね。

XMLのパースに使われるPerlモジュールについて、今後使いそうなものを列挙しておきます。全部使ったわけでもBenchmarkをとった訳でもなく、あくまでいろんなサイトを見回った結果です。これからいろいろ、調べてみないといけないですが、とりあえずアタリをつけるためのものとして。

モジュールPurePerl速度機能特徴
XML::Simple×(XML::SAX? XML::Parser=expat?)△(XML::Parser指定した時は?)HASH展開/生成基本な印象
XML::TreePPHASH展開/生成手軽に使えそう
XML::Mini×HASH展開/生成日本語がダメらしい
XML::LibXML×(libxml2)XPathXPathにより指定
XML::Parser::Lite△SOAP::Liteの一部Parse正規表現ベースのXML::Parser

参考にしたサイト