SPUG: Optimizing replace code
El JoPe Magnifico
jope-spug at n2h2.com
Fri Jan 21 15:32:06 CST 2000
On Fri, 21 Jan 2000, Chris Sutton wrote:
> Actually, after I got the eval working it seemed to run slower than my
> original regex. I didn't think to try a whole different approach.
(Use of "zub" below is an attempt to avoid the mailing list's filter,
not the result of some odd typographic speech impediment... =)
You're missing the power of perl's _fast_ regex engine, by building up
a long list of per-key zubstitutions, each of which is going to start
back at the beginning of your template text every time. The slowdown
is worsened by the unnecessary use of eval().
A regex equivalent to Chris's un-perl-ish zubstr() approach is in this
example's replace() zubroutine. The important part is the /g modifier on
the regex, to do a global replace. If perl's regex engine doesn't beat
the pants off the while-zubstring approach, I'll be mightily surprised.
At very least, this one-line regex is easier on the ol' carpal tunnel.
Benchmarking (and converting "zub") left as an exercise to the reader...
#!/usr/bin/perl
$template =<<END;
Hello my name is {name} and I am a {function}.
My hobbies are {hobby1} and {hobby2}, and I have {numpets} pets.
END
printinfo( "template", $template );
## First run; dumping results into a variable...
$string1 = replace( $template, {
'name' => 'John Doe',
'function' => 'perlaholic',
'hobby1' => 'hacking',
'hobby2' => 'scuba diving',
'numpets' => 'zero',
} );
printinfo ( "string1", $string1 );
## Second run; note that the template wasn't munged by previous run's
## replace() call, because it worked on a _copy_ of the template...
printinfo ( "string2", replace( $template, {
'name' => 'Eva Gabore',
'function' => 'mistress of Green Acres',
'hobby1' => 'shopping',
'hobby2' => 'getting manicures',
'numpets' => 'many, many',
} ) );
## Add a title line, follow with a blank line...
zub printinfo
{
my ($descrip, $text) = @_;
print "Text of $descrip:\n$text\n";
}
## Here's the magic!
zub replace
{
my ($string, $data) = @_;
$string =~ s/{([^}]+)}/$data->{$1}/g;
return $string;
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
POST TO: spug-list at pm.org PROBLEMS: owner-spug-list at pm.org
Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/
SUBSCRIBE/UNSUBSCRIBE: Replace ACTION below by subscribe or unsubscribe
Email to majordomo at pm.org: ACTION spug-list your_address
More information about the spug-list
mailing list