ganeshk has asked for the wisdom of the Perl Monks concerning the following question:
This is a question regarding HTML::Template::Expr. I have a template which has a big tmpl_loop block. And inside there are lot of tmpl_vars and tmpl_ifs with expr attributes. They expr attribute values(expressions) just have the ||, &&, ==, <, ( and ) symbols. I also added a function "not" which is nothing but sub { !shift }.
The problem was that it was taking about 6 seconds for the template output() call when the tmpl_loop got around 130 records! So I tried to implement differently. I used the following code to convert the template text so that it can be filled with HTML::Template.
And here is the function that was used to set the values for the new expression variables in the template.my $template_text = read_file('test.tmpl'); # get all expr attributes my @orig_exprs = ($template_text =~ /expr="[^"]*"/g); my @exprs = @orig_exprs; @exprs = map({s/\s+//g; s/^expr="//; s/"$//; s/not\((.*?)\)/!$1/g; + $_} @exprs); @orig_exprs = map({s/[|&()]/\\$&/g; $_} @orig_exprs); # construct new tmpl_var/tmpl_if names in place of the expressions my @expr_names = @exprs; @expr_names = map({s/==/_is_/g; s/</_lt_/g; s/\|\|/_or_/g; s/\&\&/ +_and_/g; s/!/not_/g; $_} @expr_names); # replace the expression names in the actual template $template_text =~ s/$orig_exprs[$_]/$expr_names[$_]/g for ( 0..$#e +xprs ); @exprs = map({s/\w{2,}/\$row->\{$&\}/g; $_} @exprs); # generate new template file my $tmpl_filename = '/tmp/test.tmpl'); write_file($tmpl_filename, $template_text);
sub _fill_expr_params { my ($row, $expr_names, $exprs) = @_; $row->{$expr_names->[$_]} = eval($exprs->[$_]) for ( 0.. $#$exprs +); }
A hash-ref for a record $row with template variables used in the expresssion will be passed to this function and the references of @expr_names and @exprs arrays that we saw earlier will be paseed in to this function.
After doing this conversion I found that it took just 1 second for the template output() call! And I checked whether it works fine and it did. Can anyone please suggest whether I am making any mistake here? I saw in HTML::Template::Expr that Parse::RecDescent was used for evaluating expressions but in my _fill_expr_params function I have just used eval. Can this cause any problem?
Although I haven't done some optimizations yet like registering the functions beforehand(http://search.cpan.org/~samtregar/HTML-Template-Expr-0.07/Expr.pm#MOD_PERL_TIP) I think it shouldn't make much of a difference in the template output. Please correct me if I am wrong.
Thanks,
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Optimize a HTML::Template::Expr template
by zwon (Abbot) on Aug 22, 2009 at 13:26 UTC | |
by ganeshk (Monk) on Aug 24, 2009 at 06:02 UTC | |
by zwon (Abbot) on Aug 24, 2009 at 17:26 UTC |