Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

What is the most efficient perl switch/case statement?

by synistar (Pilgrim)
on Nov 21, 2003 at 14:38 UTC ( [id://308901]=perlquestion: print w/replies, xml ) Need Help??

synistar has asked for the wisdom of the Perl Monks concerning the following question:

I often times find myself putting c like switch statements into my code (mostly CGI apps). And since there is no "official" perl way to do this I just use the one that is most aesthetically pleasing to me.

foreach $tmp (@{$input}) { SWITCH: { if($tmp =~m/$regex1/) { last SWITCH; } if($tmp =~m/$regex2/) { last SWITCH; } if($tmp eq '..') { last SWITCH; } if($tmp eq '.') { last SWITCH; } ### DEFAULT unless(-d "$path$tmp") { push @tmparr, $tmp; } } }

So, since there are so many ways to code switch/case constructs in perl (half a dozen in the camel book alone), which way is the most efficient as far as execution speed goes? Has anyone benchmarked this?

Replies are listed 'Best First'.
Re: What is the most efficient perl switch/case statement?
by Abigail-II (Bishop) on Nov 21, 2003 at 14:46 UTC
    That's a bit hard to benchmark, as it will depend on what is being switched, how many cases there are, and what the frequency of the cases is.

    For instance, if there are a hundred cases, and each case is taken about 1 out of 100 times, a hash based solution might be best. If all the cases are small non-negative integers, then an array based solution is to be preferred. But if one case is taken far more than any other, an if/elsif chain, with the common case first might be the most efficient solution.

    Abigail

Re: What is the most efficient perl switch/case statement?
by hardburn (Abbot) on Nov 21, 2003 at 14:51 UTC

    Most of the switch structures used in Perl scale linearly. They're all pretty much the same. The only exception to this is a hash that stores references to subroutines (example on page 282 of the Blue Camel).

    As pg recently pointed out, hashes have an absolute worst case runtime of O(n), but that case is so unlikely that it can be safely ignored (and perl's specific implementation does tricks to help make sure it won't happen). In the common case, hashes run very close to O(1).

    Note, though, that the constant value of hash searching is larger than a simple if tree, so if you have a small number of cases, the ifs might still be faster. If you're comparing integer, you could use a regular array instead of a hash, which will always give you O(1) efficiency with a much smaller constant.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

Re: What is the most efficient perl switch/case statement?
by jeffa (Bishop) on Nov 21, 2003 at 14:53 UTC
    This doesn't answer your question, but i'd rather use a dispatch table (a lookup hash) instead of Switch ... but i rarely care about premature optimization. In your case, you are also checking regexes, so i would probably use Tie::Hash::Regex like so:
    use strict; use warnings; use Tie::Hash::Regex; tie my %hash, 'Tie::Hash::Regex'; %hash = ( 'foo.txt' => 1, 'bar.html' => 2, '..' => undef, '.' => undef, DEFAULT => undef, ); my $arg = shift || 'DEFAULT'; my $candidate = $hash{$arg}; die "invalid arg\n" unless $candidate; print "$candidate\n";
    Since most of my work is Web based, i care more about maintainability and readability than efficiency .. but i do care about efficiency when it really matters.

    UPDATE:
    I forgot to mention CGI::Application which uses a dispatch table to control which runmode your CGI is in. If you haven't seen it yet, you really should RTFM on CGI::App ...

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    

      Actually, I do use CGI::Application. And I have used hashes as dispatch tables before (actually reinvented that wheel myself after dipping my toe in some assembly code). I usually use switch type statements for combining regex tests and other kinds of comparisons/tests (like in the example). I was not aware of Tie::Hash::Regex however. That is something I will rtfm on. CPAN is so massive I find it hard to keep up with it all (and that is a good thing).

      UPDATE:Tie::RegexpHash also seems like a pertinent module to check out. It allows one to use regexes as hash keys.

Re: What is the most efficient perl switch/case statement?
by duff (Parson) on Nov 21, 2003 at 15:30 UTC
    So, since there are so many ways to code switch/case constructs in perl (half a dozen in the camel book alone), which way is the most efficient as far as execution speed goes?

    It seems to me that you should be more interested in which method is easiest to understand. Programmer time is always worth more than CPU time. I usually use an if/elsif/else ladder since most programmers can figure out what that's doing even if they're weak on perl skills.

    But if you're really interested in which is faster, develop a large data set that would cause each branch to succeed individually or all fail, and then apply that data set to a particular switch construct. Mostly though, I think you'll be benchmarking your ability to implement the switch (And the test) rather than the particular switch-style.

    Update: Fine. For the pedants out there: Programmer time is almost always worth more than CPU time. Of course there are situations where execution speed is critical. In my experience though, if you're programming in perl, execution speed isn't your top concern. :-)

      Programmer time is always worth more than CPU time.
      That is a common myth, and understandably quite popular with programmers whose favourite programming language trades speed for programmer ease.

      But in many case, it isn't true.

      • In a fly-by-wire airplane, the flaps better go out right after the captain pulls the handle, delays because the company saved on programming time isn't acceptable.
      • If you are one of a group of websites selling "X", and making your living out of it, it's important to attract enough customers to survive. Customers base their selection of website on several things, and speed plays a rather important role.
      • If you write a chess engine, it better be fast, or else it loses on time.
      • Etc, etc, etc.
      Some things just need to be fast, and the program speed dropping below a certain treshhold is not acceptable. In such cases, CPU time is worth more than programmer time.

      Abigail

        I realize you are making a general point, but it seems unlikely that choosing the slowest switch statement implementation in Perl will cause any aircraft to go down. People learning programming should be aware that micro-optimizations of this kind rarely have any significant payoff, and are typically only worth doing after using a profiler to see where the problems lie.
Re: What is the most efficient perl switch/case statement?
by fhe (Novice) on Nov 23, 2003 at 20:48 UTC
Re: What is the most efficient perl switch/case statement?
by Anonymous Monk on Nov 21, 2003 at 15:02 UTC
    So, since there are so many ways to code switch/case constructs in perl (half a dozen in the camel book alone), which way is the most efficient as far as execution speed goes? Has anyone benchmarked this?
    Does it matter ( seems insignificant if you ask me)? Why don't you benchmark it?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://308901]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-25 21:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found