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. |