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]

Reply via email to