I embellished liz's benchmark, adding another implementation of the "switch" equivalent, and ran some tests.
I use a hash to store subroutine references, and index into the hash. This requires the same amount of code as the other methods, but I feel it is more "Perly". I think it is also more scalable.
Performance-wise, the hash runs almost neck-and-neck to the "if" - see the benchmark below.
I'm seeking feedback regarding the coding of the
line 6=> sub {$switch{5}()}, - perhaps there is a better way to express that.
Here is the benchmark code and results:
use strict;
use Benchmark;
# The Declarative part has been take out of the loop
my %switch;
%switch = (
1=> sub{print STDERR '1'},
2=> sub{print STDERR '2'},
3=> sub{print STDERR '3'},
4=> sub{print STDERR '4'},
5=> sub{print STDERR '5 or 6'},
6=> sub {$switch{5}()},
fred=> sub{print STDERR 'fred'},
__DEFAULT__=>sub{print STDERR 'default'},
);
my @loopList;
for (my $count=10; $count < 100; $count +=10){
@loopList = (1..$count, 'fred');
printf "\n====== Benchmark for %.1f%% match rate (Count= %3d)===\
+n" ,
7 * 100 / ($count + 1), $count;
RunTest();
}
##########################
sub RunTest{
timethese( 10**4 ,{
switch => sub {
sub switch{ eval{ goto "case_$_[0]" } or goto default; }
for my $expr ( @loopList ) {
switch( $expr ); {
case_1: print STDERR '1'; last;
case_2: print STDERR '2'; last;
case_3: print STDERR '3'; last;
case_4: print STDERR '4'; last;
case_5: ;
case_6: print STDERR '5 or 6'; last;
case_fred: print STDERR 'fred'; last;
default: print STDERR "default";
}
}
}, #/switch=>sub
if => sub {
for my $expr ( @loopList ) {
if ($expr eq '1') {print STDERR '1'}
elsif ($expr eq '2') {print STDERR '2'}
elsif ($expr eq '3') {print STDERR '3'}
elsif ($expr eq '4') {print STDERR '4'}
elsif ($expr eq '5' or $expr eq '6') {print STDERR '5 or 6'}
elsif ($expr eq 'fred') {print STDERR 'fred'}
else {print STDERR "default"}
}
},#/if=>sub
HashSub => sub{
for my $expr ( @loopList ) {
#print "Iter=$expr;\n";
if( exists $switch{$expr}){
$switch{$expr}()
}else{
$switch{__DEFAULT__}();
};
}; #/for
},#/UseHash
}
); #/TimeThese
}#/RunTest
--------------------------------------
Results:
>perl switchtest.pl 2> NUL
====== Benchmark for 63.6% match rate (Count= 10)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 1 wallclock secs ( 0.52 usr + 0.10 sys = 0.62 CPU) @ 16
+129.03/s (
n=10000)
if: 0 wallclock secs ( 0.41 usr + 0.09 sys = 0.50 CPU) @ 19
+960.08/s (
n=10000)
switch: 6 wallclock secs ( 5.64 usr + 0.12 sys = 5.76 CPU) @ 17
+36.71/s (n
=10000)
====== Benchmark for 33.3% match rate (Count= 20)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 1 wallclock secs ( 0.92 usr + 0.22 sys = 1.14 CPU) @ 87
+56.57/s (n
=10000)
if: 1 wallclock secs ( 0.81 usr + 0.15 sys = 0.96 CPU) @ 10
+395.01/s (
n=10000)
switch: 18 wallclock secs (17.04 usr + 0.34 sys = 17.38 CPU) @ 57
+5.24/s (n=
10000)
====== Benchmark for 22.6% match rate (Count= 30)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 1 wallclock secs ( 1.39 usr + 0.28 sys = 1.67 CPU) @ 59
+80.86/s (n
=10000)
if: 2 wallclock secs ( 1.03 usr + 0.38 sys = 1.41 CPU) @ 70
+77.14/s (n
=10000)
switch: 29 wallclock secs (28.98 usr + 0.49 sys = 29.47 CPU) @ 33
+9.29/s (n=
10000)
====== Benchmark for 17.1% match rate (Count= 40)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 3 wallclock secs ( 1.73 usr + 0.47 sys = 2.20 CPU) @ 45
+41.33/s (n
=10000)
if: 1 wallclock secs ( 1.51 usr + 0.36 sys = 1.87 CPU) @ 53
+39.03/s (n
=10000)
switch: 42 wallclock secs (41.10 usr + 0.66 sys = 41.76 CPU) @ 23
+9.46/s (n=
10000)
====== Benchmark for 13.7% match rate (Count= 50)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 3 wallclock secs ( 2.29 usr + 0.44 sys = 2.73 CPU) @ 36
+58.98/s (n
=10000)
if: 2 wallclock secs ( 1.94 usr + 0.38 sys = 2.32 CPU) @ 43
+02.93/s (n
=10000)
switch: 54 wallclock secs (52.90 usr + 0.66 sys = 53.56 CPU) @ 18
+6.72/s (n=
10000)
====== Benchmark for 11.5% match rate (Count= 60)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 3 wallclock secs ( 2.55 usr + 0.71 sys = 3.27 CPU) @ 30
+62.79/s (n
=10000)
if: 3 wallclock secs ( 2.35 usr + 0.43 sys = 2.78 CPU) @ 35
+91.95/s (n
=10000)
switch: 66 wallclock secs (64.62 usr + 0.90 sys = 65.52 CPU) @ 15
+2.62/s (n=
10000)
====== Benchmark for 9.9% match rate (Count= 70)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 4 wallclock secs ( 3.06 usr + 0.74 sys = 3.80 CPU) @ 26
+34.35/s (n
=10000)
if: 3 wallclock secs ( 2.63 usr + 0.61 sys = 3.24 CPU) @ 30
+82.61/s (n
=10000)
switch: 78 wallclock secs (76.56 usr + 0.89 sys = 77.45 CPU) @ 12
+9.11/s (n=
10000)
====== Benchmark for 8.6% match rate (Count= 80)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 4 wallclock secs ( 3.52 usr + 0.79 sys = 4.32 CPU) @ 23
+16.96/s (n
=10000)
if: 4 wallclock secs ( 3.04 usr + 0.66 sys = 3.70 CPU) @ 26
+99.06/s (n
=10000)
switch: 89 wallclock secs (88.21 usr + 1.31 sys = 89.52 CPU) @ 11
+1.71/s (n=
10000)
====== Benchmark for 7.7% match rate (Count= 90)===
Benchmark: timing 10000 iterations of HashSub, if, switch...
HashSub: 5 wallclock secs ( 3.96 usr + 0.89 sys = 4.85 CPU) @ 20
+63.13/s (n
=10000)
if: 5 wallclock secs ( 3.39 usr + 0.77 sys = 4.17 CPU) @ 24
+00.38/s (n
=10000)
switch: 101 wallclock secs (100.08 usr + 1.37 sys = 101.46 CPU) @
+ 98.56/s (
n=10000)
>
Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
Read Where should I post X? if you're not absolutely sure you're posting in the right place.
Please read these before you post! —
Posts may use any of the Perl Monks Approved HTML tags:
- a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
|
For: |
|
Use: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.
|
|