in reply to looking for a good idiom: return this if this is true

I thought it might be handy to have a benchmark on some of the contenders.

return $_ || last for subroutine() (T04) was my choice for syntax, and I was sorry to see that the for loops are so slow.

The winner was if (my $ret = subroutine()) { return $ret)} as might be expected, as this is (I would assume) the most common way to test a return value.

       Rate  T11  T02  T10  T03  T01  T04  T09  T08  T06  T07  T05
T11 37594/s   --  -8% -12% -12% -29% -31% -39% -39% -47% -47% -50%
T02 40959/s   9%   --  -4%  -4% -23% -24% -33% -33% -42% -42% -46%
T10 42581/s  13%   4%   --  -0% -20% -21% -30% -30% -40% -40% -44%
T03 42708/s  14%   4%   0%   -- -20% -21% -30% -30% -39% -39% -44%
T01 53095/s  41%  30%  25%  24%   --  -2% -13% -13% -25% -25% -30%
T04 54097/s  44%  32%  27%  27%   2%   -- -12% -12% -23% -23% -29%
T09 61265/s  63%  50%  44%  43%  15%  13%   --   0% -13% -13% -19%
T08 61265/s  63%  50%  44%  43%  15%  13%   0%   -- -13% -13% -19%
T06 70447/s  87%  72%  65%  65%  33%  30%  15%  15%   --   0%  -7%
T07 70447/s  87%  72%  65%  65%  33%  30%  15%  15%   0%   --  -7%
T05 75918/s 102%  85%  78%  78%  43%  40%  24%  24%   8%   8%   --
use strict; use Benchmark qw (cmpthese); sub froutine { 0 } sub troutine { 1 } my $tests = { 'T 01' => sub {for (troutine()) { return $_ || last; } 0;}, 'F 01' => sub {for (froutine()) { return $_ || last; } 0;}, 'T 02' => sub {for (troutine()) { return $_ if $_; } 0;}, 'F 02' => sub {for (froutine()) { return $_ if $_; } 0;}, 'T 03' => sub {$_ and return $_ for troutine(); 0;}, 'F 03' => sub {$_ and return $_ for froutine(); 0;}, 'T 04' => sub {return $_ || last for troutine(); 0;}, 'F 04' => sub {return $_ || last for froutine(); 0;}, 'T 05' => sub {if (my $ret = troutine()) { return $ret }; 0;}, 'F 05' => sub {if (my $ret = froutine()) { return $ret }; 0;}, 'T 06' => sub {return $_ if local $_ = troutine(); 0;}, 'F 06' => sub {return $_ if local $_ = froutine(); 0;}, 'T 07' => sub {if (local $_ = troutine()) { return $_ }; 0;}, 'F 07' => sub {if (local $_ = froutine()) { return $_ }; 0;}, 'T 08' => sub {return $_ while (local $_ = troutine()); 0;}, 'F 08' => sub {return $_ while (local $_ = froutine()); 0;}, 'T 09' => sub {while (local $_ = troutine()) { return $_ }; 0;}, 'F 09' => sub {while (local $_ = froutine()) { return $_ }; 0;}, 'T 10' => sub {return $_ for troutine() or (); 0;}, 'F 10' => sub {return $_ for froutine() or (); 0;}, 'T 11' => sub {return $_ for grep $_, troutine(); 0;}, 'F 11' => sub {return $_ for grep $_, froutine(); 0;}, }; for my $key (keys %$tests) { $_ = 'test'; if ($key =~ /^T/) { die unless $tests->{$key}->(); } else { die if $tests->{$key}->(); } die unless $_ eq 'test'; } cmpthese(-1, $tests); cmpthese(-1, { 'T01' => sub {$tests->{'T 01'}->(); $tests->{'F 01'}->() }, 'T02' => sub {$tests->{'T 02'}->(); $tests->{'F 02'}->() }, 'T03' => sub {$tests->{'T 03'}->(); $tests->{'F 03'}->() }, 'T04' => sub {$tests->{'T 04'}->(); $tests->{'F 04'}->() }, 'T05' => sub {$tests->{'T 05'}->(); $tests->{'F 05'}->() }, 'T06' => sub {$tests->{'T 06'}->(); $tests->{'F 06'}->() }, 'T07' => sub {$tests->{'T 07'}->(); $tests->{'F 07'}->() }, 'T08' => sub {$tests->{'T 08'}->(); $tests->{'F 08'}->() }, 'T09' => sub {$tests->{'T 09'}->(); $tests->{'F 09'}->() }, 'T10' => sub {$tests->{'T 10'}->(); $tests->{'F 10'}->() }, 'T11' => sub {$tests->{'T 11'}->(); $tests->{'F 11'}->() }, } );
-- gam3
A picture is worth a thousand words, but takes 200K.