検証方法
それぞれの関数へハッシュのリファレンスを渡して、処理の早さを見る。
以下の仮名を与えて、それをベンチマーク時のラベルとしている。
h_def: 普通のHash
h_tix: Tie::IxHash
h_ths: Tie::Hash::Sample(仮)(前回作ったもの)
注意点
普通のHashは、キーの順序を記憶できないが、
Tie::IxHashとTie::Hash::Sampleは記憶しており、
keysの値を取得すると、キーが追加した順番どおりに出てくる。
Tie::Hash::Sample(仮)はキーが追加した順番を記憶する機能だけであり、
Tie::IxHashに取って代わるものではない。
それぞれの 検証用コード/ベンチマーク結果
# データの追加 sub bench_hash_setdata{ my $ref_h = shift; my @data=('A'..'Z','a'..'z','0'..'9'); foreach my $key(@data){ $ref_h->{$key} = 1; } }
Rate h_tix h_ths h_def h_tix 2701/s -- -38% -84% h_ths 4382/s 62% -- -73% h_def 16420/s 508% 275% --
# データのクリア sub bench_hash_clear{ my $ref_h = shift; %{$ref_h} = (); }
Rate h_tix h_ths h_def h_tix 233590/s -- -45% -85% h_ths 426803/s 83% -- -73% h_def 1600000/s 585% 275% --
# データのdelete sub bench_hash_delete{ my $ref_h = shift; bench_hash_setdata($ref_h); foreach('a'..'z'){ delete $ref_h->{$_}; } }
Rate h_ths h_tix h_def h_ths 1844/s -- -14% -87% h_tix 2141/s 16% -- -85% h_def 14556/s 689% 580% -- やはりdeleteによるコストが高くついているようで、Tie::IxHashに若干遅れを取っている。
# キーの存在有無 sub bench_hash_exists{ my $ref_h = shift; bench_hash_setdata($ref_h); foreach('0'..'20'){ exists $ref_h->{$_}; } }
Rate h_tix h_ths h_def h_tix 2311/s -- -32% -84% h_ths 3386/s 47% -- -77% h_def 14881/s 544% 339% --
# ハッシュのスカラー評価値 sub bench_hash_scalar{ my $ref_h = shift; bench_hash_setdata($ref_h); scalar (%{$ref_h}); }
Rate h_tix h_ths h_def h_tix 2667/s -- -37% -83% h_ths 4266/s 60% -- -73% h_def 16000/s 500% 275% --
# keys関数 sub bench_hash_keys{ my $ref_h = shift; bench_hash_setdata($ref_h); (keys (%{$ref_h})); }
Rate h_tix h_ths h_def h_tix 2747/s -- -36% -83% h_ths 4325/s 57% -- -73% h_def 16000/s 482% 270% --
まとめ
キーの長さが1文字だけど同じ条件下のキーとして使ってるし、その辺の影響は考慮してないよ!
オリジナルの速さを考えると、よほど便利な事以外でTie::Hashで拡張するのは勿体無い!
Hashのキーの設定順だけを記録するだけなら、今回作ったもののほうがだいたい早いよ!
でもdeleteの実装は力任せ法なので時間かかってるから、IxHashより遅いよ!