無名ハッシュ生成時のメモリコピーの補足

先日の日記の実験だけど、一休みして考えると何に混乱していたのかわからない内容だ。どっからcopy on writeなどという妄想が出て来たのだろうか…

ベンチマーク実験も全てのケースにおいて無名ハッシュ生成時のメモリコピーは行われている(と思う)。無名ハッシュを生成しているのが、関数の呼び出し側か?呼び出された関数側か?だけの違い。

$ cat hash_prof2.pl
use strict;
use warnings;
use Benchmark qw/cmpthese timethese/;

my $buf =   "A" x (10*1024*1024);
my $hash = {
    data => "A" x (10*1024*1024),
};

cmpthese(
    timethese(
        0,
        {
            normal =>   sub { hoge_normal  ({ data => $buf, }); },
            hash_ref => sub { hoge_hash_ref($hash); },
        }
    )
);

sub hoge_normal {
    my $hash = shift;
    $hash->{data} .= "Z";
}

sub hoge_hash_ref {
    my $ref = shift;
    $ref->{data} .= "Z";
}

こうして無名ハッシュが作成されないようにすると、

$ perl hash_prof2.pl
Benchmark: running hash_ref, normal for at least 3 CPU seconds...
  hash_ref:  4 wallclock secs ( 3.00 usr +  0.22 sys =  3.22 CPU) @ 217148.45/s (n=699218)
    normal:  3 wallclock secs ( 1.49 usr +  1.63 sys =  3.12 CPU) @ 14.10/s (n=44)
             Rate   normal hash_ref
normal     14.1/s       --    -100%
hash_ref 217148/s 1539680%       --

やっぱり早い。