splitの高速化
splitも中で配列を作ってるんじゃなかろうかと思いまして正規表現でパースしたのと比較してみました。
・・・中略・・・
微妙な差ですな。
訂正 2007/06/25
うちの環境では結構差がでました。
ちなみに正規表現を最小マッチにしたらもう気持ち早くなりました。
sub parse_regexp_min_match { $_[0] =~ /^(.+?)\t(.+?)\t(.+?)\t(.+)/; return ($1, $2, $3, $4); }
Benchmark: timing 1000 iterations of regexp, regexp_min_match, split... regexp: 6 wallclock secs ( 6.86 usr + 0.00 sys = 6.86 CPU) @ 145.77/s (n=1000) regexp_min_match: 6 wallclock secs ( 6.03 usr + 0.00 sys = 6.03 CPU) @ 165.84/s (n=1000) split: 15 wallclock secs (14.21 usr + 0.00 sys = 14.21 CPU) @ 70.37/s (n=1000) Rate split regexp regexp_min_match split 70.4/s -- -52% -58% regexp 146/s 107% -- -12% regexp_min_match 166/s 136% 14% --
コメントで頂いたとおり結果がまるで出鱈目だった為再計測しました。
ついでに第3引数指定した場合のsplitも追加。これはあまり変わりませんでした。
正規表現との比較では普通の正規表現ではsplitの方が高速ですが、最小マッチにすると正規表現が上回りました。
環境はperl5.8.8 Celeron1.80GHzです。
#!/usr/local/bin/perl use strict; use Benchmark qw(:all); chomp (my @list = map { s/ +/\t/g; $_ } <DATA>); # 運命の5,000王子 my @large_list = (@list) x 1000; sub parse_split { return split "\t", $_[0]; } sub parse_split_3 { return split "\t", $_[0], 4; } sub parse_regexp { $_[0] =~ /^(.+)\t(.+)\t(.+)\t(.+)/; return ( $1, $2, $3, $4); } sub parse_regexp_min_match { $_[0] =~ /^(.+?)\t(.+?)\t(.+?)\t(.+)/; return ( $1, $2, $3, $4); } my $res = Benchmark::timethese(1000, { "split" => sub { parse_split($_) for @large_list }, "split_3" => sub { parse_split_3($_) for @large_list }, "regexp" => sub { parse_regexp($_) for @large_list }, "regexp_min_match" => sub { parse_regexp_min_match($_) for @large_list }, }); Benchmark::cmpthese($res); __DATA__ マリポーサ メキシコ 100000000 偽マッスルリベンジャー アタル キン肉星 1080000 ナパームストレッチ ビッグボディ カナダ 100000000 メイプルリーフクラッチ スーパーフェニックス オーストラリア 100000000 マッスルリベンジャー ゼブラ ナムビア 100000000 マッスルインフェルノ
Benchmark: timing 1000 iterations of regexp, regexp_min_match, split, split_3... regexp: 30 wallclock secs (30.02 usr + 0.01 sys = 30.03 CPU) @ 33.30/s (n=1000) regexp_min_match: 17 wallclock secs (17.14 usr + 0.00 sys = 17.14 CPU) @ 58.34/s (n=1000) split: 21 wallclock secs (20.72 usr + 0.00 sys = 20.72 CPU) @ 48.26/s (n=1000) split_3: 19 wallclock secs (19.35 usr + 0.00 sys = 19.35 CPU) @ 51.68/s (n=1000) Rate regexp split split_3 regexp_min_match regexp 33.3/s -- -31% -36% -43% split 48.3/s 45% -- -7% -17% split_3 51.7/s 55% 7% -- -11% regexp_min_match 58.3/s 75% 21% 13% --