modperl-perl_hash_lookup_faster_than_ifthenelse_stack

This is part of The Pile, a partial archive of some open source mailing lists and newsgroups.



To: <junk@mediaisotope.com>
From: "Jim Morrison [Mailing-Lists]" <junk@mediaisotope.com>
Subject: Speed of "if,elsif" versus $hash ... 
Date: Thu, 8 May 2003 10:18:37 +0100

I just had a thought.. Maybe it's not a great one, but I'd appreciate
some guidance..

I tend to start my scripts with a big if like :

	if 	( $method eq 'foo' ){ do_something(); }
	elsif ( $method eq 'bar' ){ do_somethingelse();}
	etc..

It's not too uncommon for this to become quite a big if,elsif,elsif ..
Which is ok I guess cos it's only one and it determines the whole of the
rest of the operation of the cgi..  .. But I've noticed another 'sub' I
have that returns path's to files acording to standard rules that is
also becoming quite big.. It follows the same rules :

sub path{
	my $self = shift;
	my $path = shift;
	if 	($path = 'www'){ return '/home/' . $self->{domain} .
'/www/'; }
	elsif ($path = 'foo'){ return '/bar/foo/'; }
	etc..
} 

This might get called quite frequently.. So what I'm wondering is, if I
were to make a hash :

	my %paths = ( www => \sub{ return '/home/' . $self->{domain} .
'/www/' },
			  foo => '/bar/foo',
                    etc => ....
                   )

Then looking up the path would be much quicker right?? Because if it's a
long if,elsif,elsif then I'd have to itterate through it every time,
whereas if it's a hash I don't?? (I'm not too sure of the syntax of
putting the 'sub' in, is that right?)

Anyway - the way I figure it is that any time you've got an if,elsif
statement that get's called a lot, or is particularly long, you'd be
much better of predefining it as a hash of references to functions
because it would resolve much faster.. - have I got this wrong or does
everyone else know this already? ;-)

Only other thing that bothers me is, in the first example I can quite
happily use $self->{domain} to get something out of the $self passed to
the function.. In the hash example - I'm not sure I understand the scope
of the 'sub' .. Can I pass it arguments, and how do I get to $self??


===

To: <junk@mediaisotope.com>, <modperl@perl.apache.org>
From: "Jesse Erlbaum" <jesse@erlbaum.net>
Subject: RE: Speed of "if,elsif" versus $hash ... 
Date: Thu, 8 May 2003 06:56:29 -0400

Hi Jim --

> I just had a thought.. Maybe it's not a great one, but I'd appreciate
> some guidance..
> 
> I tend to start my scripts with a big if like :
> 
> 	if 	( $method eq 'foo' ){ do_something(); }
> 	elsif ( $method eq 'bar' ){ do_somethingelse();}
> 	etc..


If you're thinking about switching from an if-elsif-else structure to a
hash table for your web apps, you might want to take a look at
CGI::Application -- 

  http://search.cpan.org/search?dist=CGI-Application

This module is the natural result of exactly that line of thinking.  In
it you may specify a table of web application methods, which are
referred to as "run modes":

  $self->run_modes(
      foo => "do_something",
      bar => "do_somethingelse"
  );

You just write the functions and CGI-App handles everything else.  Check
out this article if you want a quick primer:

  http://www.perl.com/pub/a/2001/06/05/cgi.html


===

To: junk@mediaisotope.com
From: Aaron Johnson <solution@gina.net>
Subject: Re: Speed of "if,elsif" versus $hash ...
Date: 08 May 2003 09:31:16 -0400

On Thu, 2003-05-08 at 05:18, Jim Morrison [Mailing-Lists] wrote:
> I just had a thought.. Maybe it's not a great one, but I'd appreciate
> some guidance..
> 
> I tend to start my scripts with a big if like :
> 
> 	if 	( $method eq 'foo' ){ do_something(); }
> 	elsif ( $method eq 'bar' ){ do_somethingelse();}
> 	etc..
> 
> It's not too uncommon for this to become quite a big if,elsif,elsif ..
> Which is ok I guess cos it's only one and it determines the whole of the
> rest of the operation of the cgi..  .. But I've noticed another 'sub' I
> have that returns path's to files acording to standard rules that is
> also becoming quite big.. It follows the same rules :
> 
> sub path{
> 	my $self = shift;
> 	my $path = shift;
> 	if 	($path = 'www'){ return '/home/' . $self->{domain} .
> '/www/'; }
> 	elsif ($path = 'foo'){ return '/bar/foo/'; }
> 	etc..
> } 
> 
> This might get called quite frequently.. So what I'm wondering is, if I
> were to make a hash :
> 
> 	my %paths = ( www => \sub{ return '/home/' . $self->{domain} .
> '/www/' },
> 			  foo => '/bar/foo',
>                     etc => ....
>                    )
> 
> Then looking up the path would be much quicker right?? Because if it's a
> long if,elsif,elsif then I'd have to itterate through it every time,
> whereas if it's a hash I don't?? (I'm not too sure of the syntax of
> putting the 'sub' in, is that right?)
> 
> Anyway - the way I figure it is that any time you've got an if,elsif
> statement that get's called a lot, or is particularly long, you'd be
> much better of predefining it as a hash of references to functions
> because it would resolve much faster.. - have I got this wrong or does
> everyone else know this already? ;-)
> 
> Only other thing that bothers me is, in the first example I can quite
> happily use $self->{domain} to get something out of the $self passed to
> the function.. In the hash example - I'm not sure I understand the scope
> of the 'sub' .. Can I pass it arguments, and how do I get to $self??
> 

You could do something like this:

package test;
my $obj = {};

# hardcoded for example
$obj->{domain} = 'mydomain.com';

bless $obj , 'test';

# _domain_ is a placeholder, see below
my %paths = ( www => '/home/_domain_/www/',
              foo => '/bar/foo',
              etc => '/home/user'
                   );

sub path {
    my $self = shift;
    my $dir  = shift;
    my $path = $paths{$dir};
    # our placeholder matches our object value name
    if ($path =~ /_(\w+)_/) {
        my $val = $1;
	$path =~ s/_$val\_/$self->{$val}/;
    }
    return $path;
}

foreach (keys %paths) {
    print "$_ = " , $obj->path($_) , "\n";
}


The '_' on the placeholder could be replaced with anything unique enough
for the regex.


===

the rest of The Pile (a partial mailing list archive)

doom@kzsu.stanford.edu