The stupid question is the question not asked PerlMonks

### Comment on

 Need Help??
Hello, my hearties! Support the Pirate Party! Aarhhh, matey! P-) <-- (smiley wearing an eye patch)

I ran some benchmarks with the following code to see if elsif chains were faster than a dispatch table. I pray for your wisdom as to why a chain of elsifs which should be O(N) is faster than a hash operation which ought to be O(1). Is there some Perl Magick going on here?

```#!/usr/bin/perl
# elsifbench - which is faster, a chain of elsif or a dispatch table?
# SSF 112208 042609

use strict;
use Benchmark qw/:all/;

sub random { int rand shift }
my @letters=('A'..'Z','a'..'z','0'..'9');
my \$nLetters=scalar @letters;

sub elsifchain {
my \$x=\$letters[random(\$nLetters)];
my \$y='xyzzy!' x random(1000);
if (\$x eq 'A') {
split(/!/,\$y);
}
elsif (\$x eq 'B') {
split(/!/,\$y);
}
elsif (\$x eq 'C') {
split(/!/,\$y);
}
elsif (\$x eq 'D') {
split(/!/,\$y);
}
elsif (\$x eq 'E') {
split(/!/,\$y);
}
elsif (\$x eq 'F') {
split(/!/,\$y);
}
elsif (\$x eq 'G') {
split(/!/,\$y);
}
elsif (\$x eq 'H') {
split(/!/,\$y);
}
elsif (\$x eq 'I') {
split(/!/,\$y);
}
elsif (\$x eq 'J') {
split(/!/,\$y);
}
elsif (\$x eq 'K') {
split(/!/,\$y);
}
elsif (\$x eq 'L') {
split(/!/,\$y);
}
elsif (\$x eq 'M') {
split(/!/,\$y);
}
elsif (\$x eq 'N') {
split(/!/,\$y);
}
elsif (\$x eq 'O') {
split(/!/,\$y);
}
elsif (\$x eq 'P') {
split(/!/,\$y);
}
elsif (\$x eq 'Q') {
split(/!/,\$y);
}
elsif (\$x eq 'R') {
split(/!/,\$y);
}
elsif (\$x eq 'S') {
split(/!/,\$y);
}
elsif (\$x eq 'T') {
split(/!/,\$y);
}
elsif (\$x eq 'U') {
split(/!/,\$y);
}
elsif (\$x eq 'V') {
split(/!/,\$y);
}
elsif (\$x eq 'W') {
split(/!/,\$y);
}
elsif (\$x eq 'X') {
split(/!/,\$y);
}
elsif (\$x eq 'Y') {
split(/!/,\$y);
}
elsif (\$x eq 'Z') {
split(/!/,\$y);
}
elsif (\$x eq 'a') {
split(/!/,\$y);
}
elsif (\$x eq 'b') {
split(/!/,\$y);
}
elsif (\$x eq 'c') {
split(/!/,\$y);
}
elsif (\$x eq 'd') {
split(/!/,\$y);
}
elsif (\$x eq 'e') {
split(/!/,\$y);
}
elsif (\$x eq 'f') {
split(/!/,\$y);
}
elsif (\$x eq 'g') {
split(/!/,\$y);
}
elsif (\$x eq 'h') {
split(/!/,\$y);
}
elsif (\$x eq 'i') {
split(/!/,\$y);
}
elsif (\$x eq 'j') {
split(/!/,\$y);
}
elsif (\$x eq 'k') {
split(/!/,\$y);
}
elsif (\$x eq 'l') {
split(/!/,\$y);
}
elsif (\$x eq 'm') {
split(/!/,\$y);
}
elsif (\$x eq 'n') {
split(/!/,\$y);
}
elsif (\$x eq 'o') {
split(/!/,\$y);
}
elsif (\$x eq 'p') {
split(/!/,\$y);
}
elsif (\$x eq 'q') {
split(/!/,\$y);
}
elsif (\$x eq 'r') {
split(/!/,\$y);
}
elsif (\$x eq 's') {
split(/!/,\$y);
}
elsif (\$x eq 't') {
split(/!/,\$y);
}
elsif (\$x eq 'u') {
split(/!/,\$y);
}
elsif (\$x eq 'v') {
split(/!/,\$y);
}
elsif (\$x eq 'w') {
split(/!/,\$y);
}
elsif (\$x eq 'x') {
split(/!/,\$y);
}
elsif (\$x eq 'y') {
split(/!/,\$y);
}
elsif (\$x eq 'z') {
split(/!/,\$y);
}
elsif (\$x eq '0') {
split(/!/,\$y);
}
elsif (\$x eq '1') {
split(/!/,\$y);
}
elsif (\$x eq '2') {
split(/!/,\$y);
}
elsif (\$x eq '3') {
split(/!/,\$y);
}
elsif (\$x eq '4') {
split(/!/,\$y);
}
elsif (\$x eq '5') {
split(/!/,\$y);
}
elsif (\$x eq '6') {
split(/!/,\$y);
}
elsif (\$x eq '7') {
split(/!/,\$y);
}
elsif (\$x eq '8') {
split(/!/,\$y);
}
elsif (\$x eq '9') {
split(/!/,\$y);
}
else {
warn "Huh?";
}
}

sub dispatch {
my \$x=\$letters[random(\$nLetters)];
my \$y='xyzzy!' x random(1000);
my %dispatch=(
A=>sub { split(/!/,\$y); },
B=>sub { split(/!/,\$y); },
C=>sub { split(/!/,\$y); },
D=>sub { split(/!/,\$y); },
E=>sub { split(/!/,\$y); },
F=>sub { split(/!/,\$y); },
G=>sub { split(/!/,\$y); },
H=>sub { split(/!/,\$y); },
I=>sub { split(/!/,\$y); },
J=>sub { split(/!/,\$y); },
K=>sub { split(/!/,\$y); },
L=>sub { split(/!/,\$y); },
M=>sub { split(/!/,\$y); },
N=>sub { split(/!/,\$y); },
O=>sub { split(/!/,\$y); },
P=>sub { split(/!/,\$y); },
Q=>sub { split(/!/,\$y); },
R=>sub { split(/!/,\$y); },
S=>sub { split(/!/,\$y); },
T=>sub { split(/!/,\$y); },
U=>sub { split(/!/,\$y); },
V=>sub { split(/!/,\$y); },
W=>sub { split(/!/,\$y); },
X=>sub { split(/!/,\$y); },
Y=>sub { split(/!/,\$y); },
Z=>sub { split(/!/,\$y); },
a=>sub { split(/!/,\$y); },
b=>sub { split(/!/,\$y); },
c=>sub { split(/!/,\$y); },
d=>sub { split(/!/,\$y); },
e=>sub { split(/!/,\$y); },
f=>sub { split(/!/,\$y); },
g=>sub { split(/!/,\$y); },
h=>sub { split(/!/,\$y); },
i=>sub { split(/!/,\$y); },
j=>sub { split(/!/,\$y); },
k=>sub { split(/!/,\$y); },
l=>sub { split(/!/,\$y); },
m=>sub { split(/!/,\$y); },
n=>sub { split(/!/,\$y); },
o=>sub { split(/!/,\$y); },
p=>sub { split(/!/,\$y); },
q=>sub { split(/!/,\$y); },
r=>sub { split(/!/,\$y); },
s=>sub { split(/!/,\$y); },
t=>sub { split(/!/,\$y); },
u=>sub { split(/!/,\$y); },
v=>sub { split(/!/,\$y); },
w=>sub { split(/!/,\$y); },
x=>sub { split(/!/,\$y); },
y=>sub { split(/!/,\$y); },
z=>sub { split(/!/,\$y); },
0=>sub { split(/!/,\$y); },
1=>sub { split(/!/,\$y); },
2=>sub { split(/!/,\$y); },
3=>sub { split(/!/,\$y); },
4=>sub { split(/!/,\$y); },
5=>sub { split(/!/,\$y); },
6=>sub { split(/!/,\$y); },
7=>sub { split(/!/,\$y); },
8=>sub { split(/!/,\$y); },
9=>sub { split(/!/,\$y); }
);
if (exists \$dispatch{\$x}) {
\$dispatch{\$x}->();
} else {
warn "Huh?";
}
}

cmpthese(100000,{elsif=>\&elsifchain,dispatch=>\&dispatch});

exit;

__END__

A..Z = 26 items

Benchmark: timing 100000 iterations of dispatch, elsif...
dispatch: 56 wallclock secs (55.97 usr +  0.03 sys = 56.00 CPU) @ 17
+85.71/s (n=100000)
elsif: 35 wallclock secs (35.02 usr +  0.00 sys = 35.02 CPU) @ 28
+55.51/s (n=100000)
Rate dispatch    elsif
dispatch 1786/s       --     -37%
elsif    2856/s      60%       --

A..Z, a..z, 0..9 = 62 items

Benchmark: timing 100000 iterations of dispatch, elsif...
dispatch: 93 wallclock secs (91.94 usr +  0.01 sys = 91.95 CPU) @ 10
+87.55/s (n=100000)
elsif: 41 wallclock secs (35.22 usr +  0.01 sys = 35.23 CPU) @ 28
+38.49/s (n=100000)
Rate dispatch    elsif
dispatch 1088/s       --     -62%
elsif    2838/s     161%       --

[download]```

Thanks in advance for your comments.

Humbly yours,
Aahhrh!
SSF

In reply to elsif chain vs. dispatch by sflitman

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

• 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, 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, 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.
• Log In?
 Username: Password:

What's my password?
Create A New User
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2017-08-17 08:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Who is your favorite scientist and why?

Results (284 votes). Check out past polls.

Notices?