
今のはまずかったよ、ひさいち。
遅いeachの代わりに使うspliceのメリット、デメリット | パルカワ!で、今回は遅いeachを使う代わりに高速なspliceはどうでしょう?って話。
よりにもよって、初期化を放り投げるなんて!
# … my %mapping = my @mapping = map {$_ => $_} (1..100); # ここで初期化しているけど… cmpthese -1, { splice => sub { while (my ($key, $value) = splice @mapping, 0, 2) {} }, # … };
use strict; use warnings; use Benchmark qw(:all); print "splice(), each(), keys(), values() Benchmark!!\n"; cmpthese -1, { splice => sub { my @mapping = %hash; # each()と等価にするためには、こうしないと while (my ($key, $value) = splice @mapping, 0, 2) {} }, # … };
普段は肌身離さず初期化しているんだから、こういう事故は滅多にあることじゃないんだけど。
あと、元のコード、
each()は遅い上に微妙な問題も起きやすい - Islands in the byte streamcmpthese -1, { # … keys => sub { foreach my $key(keys %hash) { } # これも each と等価じゃないよね? }, # … };
cmpthese -1, { # … keys => sub { # 等価にするなら、こう。 foreach my $key ( keys %hash ) { my $value = $hash{$key}; } }, # … };
で、上記を反映させた結果が、こちら。
Rate splice each_kv each_k map keys values splice 135/s -- -41% -63% -65% -66% -91% each_kv 226/s 68% -- -37% -41% -42% -85% each_k 359/s 167% 59% -- -7% -9% -76% map 384/s 186% 70% 7% -- -2% -75% keys 393/s 192% 74% 9% 2% -- -74% values 1520/s 1030% 571% 323% 295% 287% --
splice、keysどころかeachにも及ばないわ。
というわけで、hashをより効率良く運用できる、コンパクトで安全な構文はこう。
for my $key (keys %hash) { my $value = $hash{$key}; # and use $key and $value here }
実際、ハッシュをイテレートする際にはsortと組み合わせることも多いので、使いやすくもある。
for my $key (sort keys %hash) { my $value = $hash{$key}; # and use $key and $value here }
とはいえ、%hash
と$key
を二度書かないといけないところがイケてないとは私も思う。hash.each{ |k,v| #… }
と素直に書けるRubyistsの「わけがわからないよ」という声が聞こえてきそうだ…
Dan the Perl Monger
#!perl use strict; use warnings; use Benchmark qw(:all); my %hash = map { $_ => $_ } ( 1 .. 10000 ); cmpthese timethese - 1, { each_k => sub { while ( my $key = each %hash ) { } }, each_kv => sub { while ( my ( $key, $value ) = each %hash ) { } }, keys => sub { foreach my $key ( keys %hash ) { my $value = $_; } }, values => sub { foreach my $value ( values %hash ) { } }, map => sub { map { my $key = $hash{$_} } keys %hash; }, splice => sub { my @keys = %hash; while ( my ( $key, $value ) = splice @keys, 0, 2 ) { } }, };
このブログにコメントするにはログインが必要です。
さんログアウト
この記事には許可ユーザしかコメントができません。