2006年11月5日日曜日

[Perl] Class::Std vs Class::Accessor ベンチマーク

Perlベストプラクティス に Class::Std ネタがあったので、使い方の勉強を兼ねてベンチマーク。
��結果はある程度見えていますが。

実行環境
CentOS4.4 on VMware Perl 5.8.5

対象モジュール
Class::Std
Class::Accessor
Class::Accessor::Faster

シナリオ
・属性は id と name
・オブジェクト生成時に id=12345 name=isoya9 をセット
・id と name を取得
・id と name を再セット
・id と name を取得

ソースコード
・ClassStd.pm
package ClassStd;
use strict;
use warnings;
use Class::Std;
my %id_of :ATTR( :get id :set id :init_arg id );
my %name_of :ATTR( :get name :set name :init_arg name );

1;
__END__

・ClassAccessor.pm
package ClassAccessor;
use strict;
use warnings;
use base qw/Class::Accessor/;
__PACKAGE__->mk_accessors(qw/id name/);

1;
__END__

・ClassAccessorFast.pm
package ClassAccessorFast;
use strict;
use warnings;
use base qw/Class::Accessor::Fast/;
__PACKAGE__->mk_accessors(qw/id name/);

1;
__END__

・class_bench.pl
use strict;
use warnings;
use Benchmark ':all';

use ClassStd;
use ClassAccessor;
use ClassAccessorFast;

my $id = 12345;
my $name = "isoya9";

cmpthese(
timethese(
50000,
{
'ClassStd' => sub {
my $user = ClassStd->new({ id => $id, name => $name });
$user->get_id();
$user->get_name();
$user->set_id($id);
$user->set_name($name);
$user->get_id();
$user->get_name();
},
'ClassAccessor' => sub {
my $user = ClassAccessor->new({ id => $id, name => $name });
$user->id;
$user->name;
$user->id($id);
$user->name($name);
$user->id;
$user->name;
},
'ClassAccessorFast' => sub {
my $user = ClassAccessorFast->new({ id => $id, name => $name });
$user->id;
$user->name;
$user->id($id);
$user->name($name);
$user->id;
$user->name;
},
}
)
);

結果
Benchmark: timing 50000 iterations of ClassAccessor, ClassAccessorFast, ClassStd...
ClassAccessor: 1 wallclock secs ( 0.99 usr + 0.00 sys = 0.99 CPU) @ 50505.05/s (n=50000)
ClassAccessorFast: 1 wallclock secs ( 0.55 usr + 0.00 sys = 0.55 CPU) @ 90909.09/s (n=50000)
ClassStd: 3 wallclock secs ( 2.49 usr + 0.00 sys = 2.49 CPU) @ 20080.32/s (n=50000)
Rate ClassStd ClassAccessor ClassAccessorFast
ClassStd 20080/s -- -60% -78%
ClassAccessor 50505/s 152% -- -44%
ClassAccessorFast 90909/s 353% 80% --

予想どおり一番シンプルなClassAccessorFastがTOP。
提供される機能に差があるので、性能差が出るのは当然ですね。モジュール機能をどこまで活用するかがポイントになりそうです。
ClassStd のインサイドアウトクラスによる多重継承の振舞いはすごく清潔感を感じますが、そこまで要らないっていうのであれば ClassAccessorFast が良いですね。

0 件のコメント: