スライスでのデータアクセスのパフォーマンス

スライスでのアクセスのほうがパフォーマンスが出ると思っているが、
実際どの程度の差なのか少し気になったので測ってみた。

datafile.yaml

データ構造を考えるのがめんどくさかったので、ここから拾ってきました。
るびま

teams:
  - name:        Akudaman
    members:
      - name:    Mujo
        age:     24
        leader:  yes
      - name:    Tobokkee
        age:     25
      - name:    Donjuro
        age:     30
  - name:        Doronboo
    members:
      - name:    Doronjo
        age:     24
        leader:  yes
      - name:    Boyakkie
        age:     25
      - name:    Tonzuraa
        age:     30

array_slice.pl

use Benchmark qw( cmpthese );
use Config::YAML;

my $config  = Config::YAML->new( config => 'datafile.yaml' );
my @values  = ();

sub idx {
    @values = (
        $config->{teams}[0]{members}[0],
        $config->{teams}[0]{members}[2],
    );
}

sub idx_with_temp {
    my $temp = $config->{teams}[0]{members};
    @values = (
        $temp->[0],
        $temp->[2],
    );
}

sub slice {
    @values = @{ $config->{teams}[0]{members} }[ 0, 2 ];
}

cmpthese( 1_000_000, {
        idx             =>  sub { idx() },
        idx_with_temp   =>  sub { idx_with_temp() },
        slice           =>  sub { slice() },
});

結果

$ perl array_slice.pl
                  Rate           idx idx_with_temp         slice
idx           378788/s            --          -22%          -43%
idx_with_temp 487805/s           29%            --          -26%
slice         662252/s           75%           36%            --
$ perl array_slice.pl
                  Rate           idx idx_with_temp         slice
idx           384615/s            --          -21%          -45%
idx_with_temp 485437/s           26%            --          -30%
slice         694444/s           81%           43%            --

hash_slice.pl

use Benchmark qw( cmpthese );
use Config::YAML;

my $config  = Config::YAML->new( config => 'datafile.yaml' );
my @values  = ();

sub key {
    @values = (
        $config->{teams}[0]{members}[0]->{name},
        $config->{teams}[0]{members}[0]->{age},
    );
}

sub key_with_temp {
    my $temp = $config->{teams}[0]{members}[0];
    @values = (
        $temp->{name},
        $temp->{age},
    );
}

sub slice {
    @values = @{ $config->{teams}[0]{members}[0] }{ 'name', 'age' };
}

cmpthese( 1_000_000, {
        key             =>  sub { key() },
        key_with_temp   =>  sub { key_with_temp() },
        slice           =>  sub { slice() },
});

結果

$ perl hash_slice.pl
                  Rate key_with_temp           key         slice
key_with_temp 233100/s            --          -24%          -32%
key           306748/s           32%            --          -11%
slice         343643/s           47%           12%            --
$ perl hash_slice.pl
                  Rate           key key_with_temp         slice
key           363636/s            --           -6%          -29%
key_with_temp 387597/s            7%            --          -25%
slice         515464/s           42%           33%            --

まとめ

概ね予想通りだった。
複雑なデータ構造の(配列|ハッシュ)から、データを取り出す場合はスライスを使ったほうがパフォーマンスはいい。
(といっても微々たるものなんだろうけど。)