We use HTML::Template extensively and we are very happy with it (thank
you Sam, for a great module).
We have a couple of modules which create large reports (a several MB
in size). These reports are created by putting together several
smaller strings (each of which generated by other templates) in a
container template. Basically, there is lot of string copying going
on.
I examined the "print_to" option as an alternative to passing strings
around, but it was not always appropriate in our case.
I thought it would be faster to pass references to strings to
HTML::Template->param() instead of the strings themselves. Also, if I
could coax HTML::Template->output() to return a string ref instead of
the string itself, it could be even faster.
I have changed the output method in a couple of places to accomplish
this. My preliminary (and very unscientific) tests show that on a string
of 10 MB size, passing a reference is approximately 37% faster. Passing
a reference and accepting a reference in return value is approximately
47% faster.
Of course, for smaller strings the speedup is negligible (on a 10K
string, the speedups are 7% and 6% respectively).
I hope the overhead added by the extra checks is negligible.
FWIW, I am attaching the patch and my test results.
Sam, if you think it is reasonable, could you apply this patch to
HTML::Template?
Thanks,
/prakash
--- Template.pm.orig Wed Sep 26 14:30:30 2001
+++ Template.pm Wed Sep 26 14:33:20 2001
@@ -2375,6 +2375,15 @@
The return value is undefined when using the "print_to" option.
+You may optionally specify the "return_ref" option to get the return
+value as a reference to scalar. Example:
+
+ my $page_ref = $template->output(return_ref => 1);
+ print $$page_ref;
+
+If both "print_to" and "return_ref" are specified, "return_ref" is
+ignored.
+
=cut
use vars qw(%URLESCAPE_MAP);
@@ -2450,6 +2459,8 @@
$result .= $$line;
} elsif ($type eq 'HTML::Template::VAR' and ref($$line) eq 'CODE') {
defined($$line) and $result .= $$line->($self);
+ } elsif ($type eq 'HTML::Template::VAR' and ref($$line) eq 'SCALAR') {
+ defined($$line) and $result .= $$$line;
} elsif ($type eq 'HTML::Template::VAR') {
defined($$line) and $result .= $$line;
} elsif ($type eq 'HTML::Template::LOOP') {
@@ -2533,7 +2544,7 @@
if $options->{memory_debug};
return undef if defined $args{print_to};
- return $result;
+ return $args{return_ref} ? \$result : $result;
}
=pod
Shell command
=============
for opt in 1 2 3 4 5 6
do
echo "\n== Option ${opt} =="
time perl -I. ht.pl ${opt} > /dev/null
done
======================== BEGIN OUTPUT =========================
== Option 1 ==
length = 10485760 bytes
Options: NONE
real 0m1.325s
user 0m0.800s
sys 0m0.470s
== Option 2 ==
length = 10485760 bytes
Options: RETURN_REF
real 0m1.222s
user 0m0.690s
sys 0m0.470s
== Option 3 ==
length = 10485760 bytes
Options: PRINT_TO
real 0m1.172s
user 0m0.670s
sys 0m0.440s
== Option 4 ==
length = 10485760 bytes
Options: SCALAR_REF_PARAM
real 0m0.833s
user 0m0.480s
sys 0m0.310s
== Option 5 ==
length = 10485760 bytes
Options: SCALAR_REF_PARAM, RETURN_REF
real 0m0.699s
user 0m0.410s
sys 0m0.260s
== Option 6 ==
length = 10485760 bytes
Options: SCALAR_REF_PARAM, PRINT_TO
real 0m0.677s
user 0m0.400s
sys 0m0.210s
========================= END OUTPUT ==========================
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]