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

I have the following:

next if (($regex) and ($host !~ /$regex/));

My concern is that the script goes through the regex check even if the value $regex doesnt exist. I worry that this will consume some run time since the script would be performing a regex check on each entry even though its necessary. The larger block of code this is contained within is:

sub execute { my $i = shift; my $mib = "$oid{$i}$tftpserver"; for my $host(@routers) { chomp $host; next if (($regex) and ($host !~ /$regex/)); $filename = "$host.cfg" if ($i eq "wrnet"); my $s = Net::SNMP->session( -hostname => $host, -community => $community ); $s->set_request($mib, OCTET_STRING, $filename); my $error = $s->error; $s->set_request($oid{wrmem}, INTEGER, "1") if ($commit); $s->close; if ($error) { print "\n$error\n\n"; } elsif ($i eq "wrnet") { print "\nSuccessfully wrote config to tftpserver for $host.\n\n" +; } elsif ($i eq "confnet") { print "\nSuccessfully sent config to $host.\n\n"; } } }

humbly -c

Replies are listed 'Best First'.
Re: multiple checks on a conditional
by rchiav (Deacon) on Aug 28, 2001 at 20:35 UTC
    Actually, it won't evaluate the regex if the first half of the "and" is false. For a test, try..
    #!/usr/bin/perl -w use strict; if ( (0) and (print "test\n")) { print "True\n"; }
    "test" won't print. If you chage the 0 to a 1, it will. The reason being is that for an "and" to be true, both parts have to be true. If the first half is false, there's no need to evaluate the second half.

    Hope this helps
    Rich

Re: multiple checks on a conditional
by lestrrat (Deacon) on Aug 28, 2001 at 20:37 UTC

    I think it's not going to make that big of a difference to have it check if the $regex variable is there or not. But if it bothers you, by looking at your code I think you can just do

    sub execute { return unless $regex; # ...and then do the rest }

    As a sde note, if $regex never changes within the scope of execute(), you might want to optimize how the regex is treated, instead of worrying about conditionals

    Something like:

    sub execute { my $compiled = qr/$regex/; ..... for...{ nex if $host !~ /$compiled/; } }
Re: multiple checks on a conditional
by dvergin (Monsignor) on Aug 28, 2001 at 21:06 UTC
    An additional note on general coding practice. Apparently $regex is a global. That means it's floating around in your general name space and strange and unhappy things can happen later as the program expands -- OR you will come back to the program later and it may be tricky to figure out exactly where the value of $regex is being set.

    None of this may seem like it's important here, but imagine a different program with a global var that is altered in one sub and used in another. There's no trail of bread crumbs to lead you from the using sub to the altering sub.

    So declare it as a parameter and have pity on the next person to work with this code. (It will likely be you!) Good habits are built by practicing them on the easy stuff!

    Including lestrrat's excellent suggestions.

    # Main Code my ($i_val, $a_regex); # ...set $a_regex to some useful value (or not) # ...set $i_val execute($i_val, $a_regex); sub execute { my ($i, $regex) = @_; return unless $regex; my $compiled = qr/$regex/; my $mib = "$oid{$i}$tftpserver"; for my $host(@routers) { chomp $host; next if $host !~ /$compiled/; ... } }
    Also: Another approach to the optimization lestrrat offers is to use the /o operator:
    sub execute { my ($i, $regex) = @_; return unless $regex; my $mib = "$oid{$i}$tftpserver"; for my $host(@routers) { chomp $host; next if $host !~ /$regex/o; # HERE ... } }