Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Function speeds: lc() vs. eq vs. =~

by Clownburner (Monk)
on Apr 16, 2001 at 21:58 UTC ( [id://72886]=perlquestion: print w/replies, xml ) Need Help??

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

OK, here's a quicky for you:

I have a program that needs to check the results of a DBI call against a list of possible values, and set other variables based on that. Since this is supposed to run interactively and could have to evaluate a huge number of replies, speed is a huge factor.

'Effective Programming in Perl' says that the eq operator is faster than using a RegExp '=~', but what about if you have to do a case-insensitive search? Are multiple 'eq' operations faster than one RegExp? What about an lc()

For example, which of these would run fastest:

if (lc($type) eq 'cr') { $foo = 1 } -or- if ($type eq 'cr' or $type eq 'CR') { $foo = 1 } -or- if ($type =~ /CR/i) { $foo = 1 }
Thanks in advance...
Signature void where prohibited by law.

Replies are listed 'Best First'.
(tye)Re: Function speeds: lc() vs. eq vs. =~
by tye (Sage) on Apr 16, 2001 at 22:21 UTC

    Firstly, none of your cases are the same. You could use:

    if( $type =~ /^CR\Z/i ) # or if( $type =~ /^CR$/i ) # if you want to allow for ignoring trailing newlines
    and you'd have to use: if(  $type eq 'cr'  ||  $type eq 'CR'  ||  $type eq 'Cr'  ||  $type eq 'cR'  )

    I'd argue that the speed difference is of extremely little importance in this case.

    Use whichever makes the most readable code. So that eliminates the second one in my book. I like the first one.

            - tye (but my friends call me "Tye")
      Good point, but I guess I should have been more precise about my situation, you see the database will only ever be in two states, cr or CR and never Cr or cR. So while checking for the last two states is OK it's really not required and if you're going to give each option as separate it's not really required.

      But thanks! I never played with Benchmark before, now I have new perl toys to play with! :-)
      Signature void where prohibited by law.
Re: Function speeds: lc() vs. eq vs. =~
by Fastolfe (Vicar) on Apr 16, 2001 at 22:11 UTC
    Why don't you try them?
    use Benchmark 'timethese'; sub eq_alone { $_[0] eq 'cr' || $_[0] eq 'CR'; } sub lc_eq { lc($_[0]) eq 'cr'; } sub regex { $_[0] =~ /^cr$/i; } timethese (2_000_000, { eq_alone => sub { eq_alone('cr'); eq_alone('CR'); }, lc_eq => sub { lc_eq('cr'); lc_eq('CR'); }, regex => sub { regex('cr'); regex('CR'); }, }); __END__ Benchmark: timing 2000000 iterations of eq_alone, lc_eq, regex... eq_alone: 22 secs (21.48 usr 0.00 sys = 21.48 cpu) lc_eq: 22 secs (22.76 usr 0.00 sys = 22.76 cpu) regex: 25 secs (24.88 usr 0.00 sys = 24.88 cpu)
    In short, using lc is roughly just as expensive as a simple 'eq', giving us the same results as doing a double 'eq'. Using a regex adds only a few seconds.

    In many cases like this (where the numbers are so close), performance matters less than readability. Use whatever is easier for you to comprehend and easiest for future maintainers to read. I usually vote for using lc in cases like this.

Re: Function speeds: lc() vs. eq vs. =~
by btrott (Parson) on Apr 16, 2001 at 22:12 UTC
    use Benchmark.

    I did a benchmark and came up with the following:

    Benchmark: timing 1000000 iterations of eq, lc, re... eq: 3 wallclock secs ( 2.76 usr + 0.00 sys = 2.76 CPU) lc: 3 wallclock secs ( 2.69 usr + 0.00 sys = 2.69 CPU) re: 3 wallclock secs ( 3.13 usr + 0.00 sys = 3.13 CPU)
    lc is your first code snippet, eq the second, and re the third.

    You *really* don't need to worry about the differences in speed, unless you're doing this 100000 times or something like that.

    Seriously: don't try to optimize things like this. Testing case-insensitive equality is *such* a fast operation that you shouldn't be worrying about it--yes, even in an interactive situation.

    Instead worry about Getting It Right. For example, what does your second code snippet do if $type is 'Cr' or 'cR'? Maybe you don't think you need to worry about those things, but I say you should: it's definitely more important than worrying about a couple of milliseconds per every 100000 case-insensitive equality checks.

Re: Function speeds: lc() vs. eq vs. =~
by suaveant (Parson) on Apr 16, 2001 at 22:04 UTC
    Benchmark them... It's straightforward to use and comes with perl. That'll give you the best idea.

    I'm guessing =~ is the slowest, but Benchmark will tell you
                    - Ant

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2024-04-20 00:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found