given-when を dispatcher としてつかう場合の注意事項
せっかく given-when 構文をつかえるのだから、以下のように Dispatcher を書けばいいのではないか、という話があったので実際つかってみていたのだが、このような書き方は非常に低速であることがわかった(too slow)。
use 5.010; sub dispatch { my ($class, $c) = @_; given ([$c->request->method, $c->request->path_info]) { when (['GET', '/']) { return call("Root", 'index'); } ... } }
以下のようなベンチマークスクリプトをうごかすと 25倍遅い。
use strict; use warnings; use Benchmark qw/:all/; use 5.010; my $method = "GET"; my $path = "/"; if (@ARGV) { $method = 'POST'; $path = '/entry'; } print $],$/; cmpthese( -1, { 'given-when' => \&given_when, 'if-else' => \&if_else, }, ); sub if_else { if ($method eq 'GET' && $path eq '/') { return 'root'; } elsif ($method eq 'GET' && $path eq '/history') { return 'history'; } elsif ($method eq 'POST' && $path eq '/entry') { return 'add_entry'; } else { return '404'; } } sub given_when { given ([$method, $path]) { when (['GET', '/']) { return "root"; } when (['GET', '/history']) { return "history"; } when (['POST', '/entry']) { return "add_entry"; } default { return '404'; } } }
5.010001 Rate given-when if-else given-when 84329/s -- -96% if-else 2323548/s 2655% --