健康診断
健康診断へ行って血を取ってきました。前回はチューブ通して採血の容器に取ってたのが今回は針から直結するようになって、それのおかげか何なのかは分りませんが採血スピードが向上して地味に嬉しかったです。痛いのは嫌いなのです…
blessとMouseの速度比較
すこし気になってblessとMouse、その他の速度比較。いろんなところでやられてるので今更自分でする事でもないでしょうが。なおblessで作るクラスは手を抜いて型制限などの実装はせずアクセサを用意して値を操作するだけにしました。適当適当。
いまさら聞けない「Moose」超入門を参考にblessとMouseのコードを書き足しました。以下の処理の速度を比較しています。
- hoge/fugaのアクセサを持ったクラスをnew
- 初期値はfugaに1
- hogeに'bbb'を代入
- fugaの値を取得
- hogeの値を取得
cost.pl
# おまじないしない場合
package MooseTest;
use Moose;
has 'hoge' => ( is => 'rw', isa => 'Str' );
has 'fuga' => ( is => 'rw', isa => 'Int' );
no Moose;
1;
# おまじないする場合
package MooseTest_mi;
use Moose;
has 'hoge' => ( is => 'rw', isa => 'Str' );
has 'fuga' => ( is => 'rw', isa => 'Int' );
__PACKAGE__->meta->make_immutable; # おまじない
no Moose;
1;
# おまじないしない場合
package MouseTest;
use Mouse;
has 'hoge' => ( is => 'rw', isa => 'Str' );
has 'fuga' => ( is => 'rw', isa => 'Int' );
no Mouse;
1;
# おまじないする場合
package MouseTest_mi;
use Mouse;
has 'hoge' => ( is => 'rw', isa => 'Str' );
has 'fuga' => ( is => 'rw', isa => 'Int' );
__PACKAGE__->meta->make_immutable; # おまじない
no Mouse;
1;
# Class::Accessor を使った場合
package ClassAccessorTest;
use strict;
use warnings;
use base 'Class::Accessor';
__PACKAGE__->mk_accessors(qw/hoge fuga/);
1;
# Class::Accessor::Fast を使った場合
package ClassAccessorFastTest;
use strict;
use warnings;
use base 'Class::Accessor::Fast';
__PACKAGE__->mk_accessors(qw/hoge fuga/);
1;
# perl5 OOP の場合
package Bless;
use strict;
use warnings;
sub new {
my $class = shift;
my $self = shift || {};
return bless $self, $class;
}
sub hoge {
my $self = shift;
if (@_) {
$self->{hoge} = shift;
} else {
$self->{hoge};
}
}
sub fuga {
my $self = shift;
if (@_) {
$self->{fuga} = shift;
} else {
$self->{fuga};
}
}
1;
package main;
use strict;
use warnings;
use Benchmark qw(cmpthese timethese);
cmpthese timethese(100000, {
moose => sub {
my $moose = MooseTest->new( fuga => 1 );
$moose->hoge('bbb');
$moose->fuga;
$moose->hoge;
},
moose_mi => sub {
my $moose = MooseTest_mi->new( fuga => 1 );
$moose->hoge('bbb');
$moose->fuga;
$moose->hoge;
},
mouse => sub {
my $mouse = MouseTest->new( fuga => 1 );
$mouse->hoge('bbb');
$mouse->fuga;
$mouse->hoge;
},
mouse_mi => sub {
my $mouse = MouseTest_mi->new( fuga => 1 );
$mouse->hoge('bbb');
$mouse->fuga;
$mouse->hoge;
},
accessor => sub {
my $class = ClassAccessorTest->new({ fuga => 1 });
$class->hoge('bbb');
$class->fuga;
$class->hoge;
},
accessor_fast => sub {
my $class = ClassAccessorFastTest->new({ fuga => 1 });
$class->hoge('bbb');
$class->fuga;
$class->hoge;
},
bless => sub {
my $class = Bless->new({ fuga => 1 });
$class->hoge('bbb');
$class->fuga;
$class->hoge;
},
});
結果はこんな感じになりました。何回か実行するとばらつくので3つほど結果を書き出しています。
Benchmark: timing 100000 iterations of accessor, accessor_fast, bless, moose, moose_mi, mouse, mouse_mi...
accessor: 2 wallclock secs ( 1.19 usr + 0.00 sys = 1.19 CPU) @ 84033.61/s (n=100000)
accessor_fast: 0 wallclock secs ( 0.58 usr + 0.00 sys = 0.58 CPU) @ 172413.79/s (n=100000)
bless: 1 wallclock secs ( 0.41 usr + 0.00 sys = 0.41 CPU) @ 243902.44/s (n=100000)
moose: 21 wallclock secs (21.26 usr + 0.02 sys = 21.28 CPU) @ 4699.25/s (n=100000)
moose_mi: 2 wallclock secs ( 1.67 usr + 0.00 sys = 1.67 CPU) @ 59880.24/s (n=100000)
mouse: 0 wallclock secs ( 0.51 usr + 0.00 sys = 0.51 CPU) @ 196078.43/s (n=100000)
mouse_mi: -1 wallclock secs ( 0.51 usr + 0.00 sys = 0.51 CPU) @ 196078.43/s (n=100000)
Rate moose moose_mi accessor accessor_fast mouse_mi mouse bless
moose 4699/s -- -92% -94% -97% -98% -98% -98%
moose_mi 59880/s 1174% -- -29% -65% -69% -69% -75%
accessor 84034/s 1688% 40% -- -51% -57% -57% -66%
accessor_fast 172414/s 3569% 188% 105% -- -12% -12% -29%
mouse_mi 196078/s 4073% 227% 133% 14% -- 0% -20%
mouse 196078/s 4073% 227% 133% 14% 0% -- -20%
bless 243902/s 5090% 307% 190% 41% 24% 24% --
Benchmark: timing 100000 iterations of accessor, accessor_fast, bless, moose, moose_mi, mouse, mouse_mi...
accessor: 1 wallclock secs ( 0.87 usr + 0.00 sys = 0.87 CPU) @ 114942.53/s (n=100000)
accessor_fast: 0 wallclock secs ( 0.56 usr + 0.00 sys = 0.56 CPU) @ 178571.43/s (n=100000)
bless: 1 wallclock secs ( 0.43 usr + 0.00 sys = 0.43 CPU) @ 232558.14/s (n=100000)
moose: 18 wallclock secs (18.30 usr + 0.00 sys = 18.30 CPU) @ 5464.48/s (n=100000)
moose_mi: 2 wallclock secs ( 1.57 usr + 0.00 sys = 1.57 CPU) @ 63694.27/s (n=100000)
mouse: 0 wallclock secs ( 0.55 usr + 0.00 sys = 0.55 CPU) @ 181818.18/s (n=100000)
mouse_mi: 1 wallclock secs ( 0.65 usr + 0.00 sys = 0.65 CPU) @ 153846.15/s (n=100000)
Rate moose moose_mi accessor mouse_mi accessor_fast mouse bless
moose 5464/s -- -91% -95% -96% -97% -97% -98%
moose_mi 63694/s 1066% -- -45% -59% -64% -65% -73%
accessor 114943/s 2003% 80% -- -25% -36% -37% -51%
mouse_mi 153846/s 2715% 142% 34% -- -14% -15% -34%
accessor_fast 178571/s 3168% 180% 55% 16% -- -2% -23%
mouse 181818/s 3227% 185% 58% 18% 2% -- -22%
bless 232558/s 4156% 265% 102% 51% 30% 28% --
Benchmark: timing 100000 iterations of accessor, accessor_fast, bless, moose, moose_mi, mouse, mouse_mi...
accessor: 1 wallclock secs ( 0.90 usr + 0.00 sys = 0.90 CPU) @ 111111.11/s (n=100000)
accessor_fast: 0 wallclock secs ( 0.75 usr + 0.00 sys = 0.75 CPU) @ 133333.33/s (n=100000)
bless: 1 wallclock secs ( 0.47 usr + 0.00 sys = 0.47 CPU) @ 212765.96/s (n=100000)
moose: 22 wallclock secs (21.62 usr + 0.01 sys = 21.63 CPU) @ 4623.21/s (n=100000)
moose_mi: 1 wallclock secs ( 1.61 usr + 0.00 sys = 1.61 CPU) @ 62111.80/s (n=100000)
mouse: 1 wallclock secs ( 0.45 usr + 0.00 sys = 0.45 CPU) @ 222222.22/s (n=100000)
mouse_mi: 0 wallclock secs ( 0.45 usr + 0.00 sys = 0.45 CPU) @ 222222.22/s (n=100000)
Rate moose moose_mi accessor accessor_fast bless mouse_mi mouse
moose 4623/s -- -93% -96% -97% -98% -98% -98%
moose_mi 62112/s 1243% -- -44% -53% -71% -72% -72%
accessor 111111/s 2303% 79% -- -17% -48% -50% -50%
accessor_fast 133333/s 2784% 115% 20% -- -37% -40% -40%
bless 212766/s 4502% 243% 91% 60% -- -4% -4%
mouse_mi 222222/s 4707% 258% 100% 67% 4% -- 0%
mouse 222222/s 4707% 258% 100% 67% 4% 0% --
Mouseが爆速でblessより速いこともあるようです。にわかに信じられないのですが。何か最適化されているものでもあるのでしょうか?ちゃんと中身を見ないといけませんね。
思う事
速度というのは最近気にしているテーマで、Webアプリの1リクエストのレスポンスタイムが10msと100msとあったとして、それの時間差が90msと何となく微々たる物のように思う物でも分間10リクエストとして合計100msと1000msになり差が900msとどんどん大きくなっていくのが恐ろしいなぁと思ったりしています。もしもこれが分間じゃなくて秒間だったら?10リクエストじゃなくて100リクエストだったら?1000リクエストだったら?…まだ実感の伴わない話なのでアレですが今後直面する問題だろうなと感じています。モダンだ流行だと色々なものに飛びつくのも勉強になって良いですが、ただ実際それが実用に堪えうるのかどうかちゃんと検証することも覚えないといけないなと。そんなことを考えています。