>> When a TMPL_LOOP is encountered, H::T needs to create (for want of a
>> better description) a child context, that contains only the template
>> variables for the child.  Each child context is effectively a new
>> H::T object, so that the very top H::T object accumulates the output
>> from each child.
>
> OK, that makes sense.  I don't understand why DProf is showing more
> BEGIN blocks in this case though.  As far as I could see from a scan
> of the code it should be just instantiating ->new objects rather than
> re-evalling, so I don't understand where this is coming from.
My experience with DProf has been good and bad; I find the output a
little confusing.... Usually "print nanosecond-timer" gives me the good oil.
>
>> By removing the LOOP, you are effectively completely avoiding the
>> child context thus saving quite a significant amount of processing.
>
> Ah!  Even if the child process is used to process a loop of 20 items,
> if the parent context is large, the whole context is copied non-lazily
> to the child?
Depends if "global_vars" is set; although, that option doesn't
immediately cause too much of a slow down.
>
> We have tried running the template output with the largest context
> object (dictionary for localisation) turned off, without noticing
> any impact on the pathological case.
did you mean "largest object 'associate'd with H::T"?

In any case, most of the code is O(n) for template size and O(1) or
similar for param-value lookups.
>
>> If you are looking for performance increases, you should start simply
>> by printing a hi-res time from various points within "output()".  I
>> have done this previously and found that I was able to find a
>> dramatic increase in performance, just by removing foreach() loops. **
>
> That's a possibility, though I think loops are fairly basic
> functionality that I'd like not to have to prune from template code...
Past programming experience tells me that "for { for { ... }}" is
O(n^2)... so that is always the first thing I look for.  H::T has this
case at the very start of the output() code block -> so its a good
candidate for profiling.
>
>> regards,
>> Mathew Robertson
>>
>> ** If you interested, I can send you a patch which ("works for me")
>> speed's up the template-variable symbol resolution.  This patch has
>> achieved close to 20x speed up under some circumstances. Most
>> templates are speed up by about 1.5x.
>
> Shiny!  I'd be interested to take a look,
No sweat.  This replaces the "associate magic" code block lines 2658 to
2686 (H::T 2.9, 2.8 is similar):

  # support the associate magic, searching for undefined params and
  # attempting to fill them from the associated objects.
  if (scalar(@{$options->{associate}})) {
    my @undef_params;
    foreach my $param (keys %{$self->{param_map}}) {
      next if (defined $self->param($param));
      push @undef_params, $param;
    }
    if (scalar(@undef_params)) {
      my $value;
      # if case sensitive mode or no CGI objects, we can use the fast path
      if ($options->{case_sensitive} or (grep { !/^1/ } map {
UNIVERSAL::isa($_,'HTML::Template') } @{$options->{associate}}) == 0) {
        foreach my $param (@undef_params) {
          foreach my $associated_object (reverse @{$options->{associate}}) {
            $value = $associated_object->param($param);
            next unless (defined $value);
            $self->param($param, scalar $value);
            last;
          }
        }
      } else {
        my %case_map;
        foreach my $associated_object (@{$options->{associate}}) {
          map { $case_map{$associated_object}{lc($_)} = $_ }
$associated_object->param();
        }
        my $associated_param;
        foreach my $param (@undef_params) {
          foreach my $associated_object (reverse @{$options->{associate}}) {
            $associated_param = $case_map{$associated_object}{$param};
            next unless (defined $associated_param);
            $value = $associated_object->param($associated_param);
            next unless (defined $value);
            $self->param($param, scalar $value);
            last;
          }
        }
      }
    }
  }

You probably want to do a timing check using the old code vs this new
code - just to ensure that it isn't making the problem worse.

cheers,
Mathew

-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Html-template-users mailing list
Html-template-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/html-template-users

Reply via email to