http://qs321.pair.com?node_id=605529


in reply to Re^2: Just 1 line explanation
in thread Just 1 line explanation

benchmarks are funny things. have i made a mistake here, or is grep faster than first in this case? the real win is factoring out the call to param():
use strict; use Benchmark qw(cmpthese); use List::Util; ## a 'reasonable' worst-case scenario? first of list of twenty .. my @display_files = qw( one two three four five six seven eight nine ten eleven twelve thi +rteen fourteen fifteen sixteen seventeen eighteen nineteen twenty ); sub param { 'one' } cmpthese( -2, { grep_param => sub { unless( grep { $_ eq param('select') } @display_files ) { 1; } + }, param_grep => sub { my $select = param('select'); unless( grep { $_ eq $select } @display_files ) { 1; } }, found => sub { my $select = param('select'); my $found; foreach (@display_files) { if ($_ eq $select) { $found = 1; last; } } unless ($found) { 1; } }, first => sub { my $select = param('select'); my $found = List::Util::first { $_ eq $select } @display_files +; unless ($found) { 1; } } });
produces:
               Rate grep_param      first param_grep      found
grep_param  47285/s         --       -69%       -81%       -92%
first      154996/s       228%         --       -36%       -73%
param_grep 244086/s       416%        57%         --       -57%
found      565517/s      1096%       265%       132%         --
interestingly, change sub param to return undef (to get a failing test) and i get:
               Rate grep_param      first      found param_grep
grep_param  81919/s         --       -18%       -61%       -68%
first       99685/s        22%         --       -52%       -61%
found      207714/s       154%       108%         --       -18%
param_grep 254449/s       211%       155%        22%         --
personally, i think grep is the clearest and most familiar idiom, and for a shortish list of @display_files the performance gains of using the for () { ... last; } aren't worth it, especially if the failure case is common.