[boulder.pm] line/loop optimization?

Jim Baker boulder-pm at jim-baker.com
Tue May 8 12:42:32 CDT 2001


If we're doing dynamic templates, my favorite is something like the
following.  It slurps the template in from STDIN, dynamically interpolating
in the variables accessible in the namespace (such as %opt):

use strict;
use warnings;

my %opt;
$opt{foo} = 'abc';
$opt{fum} = 'xyz';
my $template = do { no strict; local $/; <> };
my $filled_template = eval qq[qq[$template]];

print $template;
print $filled_template;


It's left as an exercise for the reader to prevent unbalanced quotes (use
quote-to-here instead of brackets) and variable interpolation accessing
portions of the namespace it shouldn't (use Safe of course).

All of the solutions presented so far are why we like Perl (dynamic code,
dynamic quotes, dynamic regexes, etc.).

- Jim

-----Original Message-----
From: owner-boulder-pm-list at pm.org
[mailto:owner-boulder-pm-list at pm.org]On Behalf Of rise
Sent: Tuesday, May 08, 2001 11:07 AM
To: Boulder Perl Mongers
Subject: Re: [boulder.pm] line/loop optimization?


On Tue, 8 May 2001, Robert L. Harris wrote:

> @Keys=keys(%ConfigOptions);
> while(<TemplateIn>) {
>   chomp;
>   $Line=$_;
>   foreach $i (@Keys) {
>     $Line =~ s/$i/$ConfigOptions{$i}/;
>   }
> }
>
>
> Is there a better way to do a line by line substitution instead of looping
> through @Keys each line?

Three immediate (speed, not necessarily maintainability) optimizations
occur to me:
a) If each Option is a fixed string, don't check each one individually.
   Instead do something like /(Option1|Option2|Option3/$ConfigOptions{$1}/
   since the match will contain your hash key for a fixed string match.
b) Use the qr{} quoting operation to get a "compiled" regex so that you're
   not reinterpolating for each line[1].
c) If values only change between runs you can use the /o modifier to make
   sure perl doesn't recompile the regex.

Basic strategy (untested):

@Keys=keys(%ConfigOptions);
# this next bit can be done in one operation
$OptionRegexString = join('|', @Keys);
$OptionRegexRef =  qr/$OptionRegexString/o;

while(<TemplateIn>) {
  chomp;
  $Line=$_;
  $Line =~ s/($OptionRegexRef)/$ConfigOptions{$1}/;
}


[1] perldoc perlop, in the section "Regexp Quote-Like Operators"
--
Jonathan Conway 	   The thing about Unix is that all the hoops are
rise at knavery.net           flaming, so at least you know where they are...






More information about the Boulder-pm mailing list