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;
}