#まえがき
Perlには他の多くの言語にはあるSwitch文が実装されておらず、モジュールとして拡張することで一応書けなくもないが、速度が遅かったりバグが見つかったりなどが理由で利用が推奨されていないということは知識として知ってはいたが、実際に使ったことがなかったので今回物は試しにどれくらいの遅いものなのか調べてみた。
#準備
まずは use Switch;
を使えるようにしましょう。
$ cpanm Switch
--> Working on Switch
Fetching http://www.cpan.org/authors/id/C/CH/CHORNY/Switch-2.17.tar.gz ... OK
Configuring Switch-2.17 ... OK
Building and testing Switch-2.17 ... OK
Successfully installed Switch-2.17
1 distribution installed
そしてどうやらPerlでもSwitch文はデフォで使える様になっていたことを知る。
ただし、switchはgiven、caseはwhenとして書く決まりのようだ。
(今まで全部if~elseで書いてたのは一体…)
こいつの速度も一緒に調べてみる。
#実験
use strict;
use warnings;
use Switch;
use feature "switch";
use Benchmark qw( :all );
use constant COUNT => -1;
my @subjects = ( "kokugo","suugaku","rika","shakai","eigo" );
my $switch_case = sub {
for my $subject (@subjects) {
switch ($subject) {
case (/kokugo/) { return "Japanese"; }
case (/suugaku/) { return "Math"; }
case (/rika/) { return "Scinence"; }
case (/shakai/) { return "Social Studies"; }
else { return "something else"; }
}
}
};
my $given_when = sub {
for my $subject (@subjects) {
given ($subject) {
when (/kokugo/) { return "Japanese"; }
when (/suugaku/) { return "Math"; }
when (/rika/) { return "Scinence"; }
when (/shakai/) { return "Social Studies"; }
default { return "something else"; }
}
}
};
my $if_else = sub {
for my $subject (@subjects) {
if ($subject =~ /kokugo/) { return "Japanese"; }
elsif ($subject =~ /suugaku/) { return "Math"; }
elsif ($subject =~ /rika/) { return "Science"; }
elsif ($subject =~ /shakai/) { return "Social Studies"; }
else { return "something else"; }
}
};
cmpthese (COUNT,{
switch_case => $switch_case,
given_when => $given_when,
if_else => $if_else
});
#結果
$ perl switch_vs_given.pl
switch_case 149593/s -- -95% -97%
given_when 2880703/s 1826% -- -41%
if_else 4871702/s 3157% 69% --
switch文…こんなに遅いのかってくらい遅い…。
そして、一応代わりに実装されたというgiven_whenですらこの速度。
恐るべし、if_else文…。