萌えキャラとは何だったのか

ギークにも絵描きにもなれない者の末路

健康診断

健康診断へ行って血を取ってきました。前回はチューブ通して採血の容器に取ってたのが今回は針から直結するようになって、それのおかげか何なのかは分りませんが採血スピードが向上して地味に嬉しかったです。痛いのは嫌いなのです…

blessとMouseの速度比較

すこし気になってblessとMouse、その他の速度比較。いろんなところでやられてるので今更自分でする事でもないでしょうが。なおblessで作るクラスは手を抜いて型制限などの実装はせずアクセサを用意して値を操作するだけにしました。適当適当。

いまさら聞けない「Moose」超入門を参考にblessとMouseのコードを書き足しました。以下の処理の速度を比較しています。

  1. hoge/fugaのアクセサを持ったクラスをnew
    • 初期値はfugaに1
  2. hogeに'bbb'を代入
  3. fugaの値を取得
  4. 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リクエストだったら?…まだ実感の伴わない話なのでアレですが今後直面する問題だろうなと感じています。モダンだ流行だと色々なものに飛びつくのも勉強になって良いですが、ただ実際それが実用に堪えうるのかどうかちゃんと検証することも覚えないといけないなと。そんなことを考えています。