hi
please excuse this rather lengthy mail ...

im a bit curious about the eval function in perl.
consider the ready-to-run script below containing 3 different
subroutines which in fact are doing the same, but with different
efficiency. i have included a switch to easily try them all.
the subroutines jobs are to look thru some content for a certain pattern
and when found replace that pattern with a value which it look up inside
a txt.file, called "dbm.txt". this txt file im testing on looks
currently exactly like this:

<tag id=1>:basic=3.00:private=13.00
<tag id=2>:basic=4.00:private=23.00
<tag id=3>:basic=5.00:private=33.00



version1 is pretty much straight forward looping.
version2 is how i thought it should be done with the eval function, as i understand
the pattern(s) then get compiled only once.
version3 is a direct version (in fact it is the printed output of the
eval in version2).

version 3 is slightly faster than version 1, which is considerably
faster than version2.

my only question is, how come the eval version is slower than
version1 (and can i make it faster)?

thanks
allan


#!perl -w

use strict;

my $content  = "
this is various content containg tags like these:
<tag id=1> (probably more content)
<tag id=2> (probably more content)
";

my $cust = "private";
my ($version1Response, $version2Response, $directResponse);
my $switch = 1;

my $start = (times)[0];

for (my $i=0;$i<=300;$i++) {
        if ($switch == 1) {
                $version1Response = normalVersion($content, $cust);
                print $version1Response;
        } elsif ($switch == 2) {        
                $version2Response = evalVersion($content, $cust);
                print $version2Response;
        } else {
                $directResponse = directVersion($content, $cust);
                print $directResponse;
        }
        
}

my $finish = (times)[0];
my $result = $finish - $start;
print "\nthis took $result";


############version 1############

sub normalVersion {
        (my $output, my $customer) = @_;
        open (FILE, "dbm.txt"); 
        while (<FILE>) {
                chomp;
                while (/(<tag[^>]+id=\d+>).+$customer=([^:]+)/g) {
                        my $tag = $1;
                        my $val = $2;
                        $output =~ s/$tag/$val/g
                }
        }
        close(FILE);
        return  $output; 
}

############version 2############

sub evalVersion {
        (my $output, my $customer) = @_;
        my $max = 2; #this will be known
        my ($tag, $val);
        my $code = "open (FILE, \"dbm.txt\");\n";
        $code .= 'while (<FILE>) {';
        $code .= "\nchomp;";
        for (my $j=1;$j<=$max;$j++) {
                        $code .= "\n\twhile (/(<tag[^>]+id=$j>).+$customer=([^:]+)/g) 
{\n";
#fill it with constants
                        $code .= "\t\t\$tag = \$1;\n";
                        $code .= "\t\t\$val = \$2;\n";
                        $code .= "\t\t\$output =~ s/\$tag/\$val/go\n"; #not sure of /o 
benefit
                        $code .= "\t}\n";
        }
        $code .= "}\n"; 
        $code .= "close (FILE);\n";
        $code .= "return  \$output;";
        eval $code;
}

##########direct############

sub directVersion {
        (my $output, my $customer) = @_;
        open (FILE, "dbm.txt");
        while (<FILE>) {
        chomp;
                while (/(<tag[^>]+id=1>).+private=([^:]+)/g) {
                        my $tag = $1;
                        my $val = $2;
                        $output =~ s/$tag/$val/go
                }
                while (/(<tag[^>]+id=2>).+private=([^:]+)/g) {
                        my $tag = $1;
                        my $val = $2;
                        $output =~ s/$tag/$val/go
                }
        }
        close (FILE);
        return  $output;
}

Reply via email to