LoginSignup
11
7

More than 5 years have passed since last update.

perlで switch vs when vs if

Last updated at Posted at 2017-06-03

まえがき

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文…。

11
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7