For a little background...

I had a module that was a simple TT style variable
replacer.  All it could handle were things like [% a %] or [% a.0 %]
or [% a.a.0 %].  It didn't allow for argument passing, or directives,
or operators.  All it did was variables.  The perldoc made clear the
limitations and said to use Template::Toolkit if anything more
complicated was desired.

Years went on.  I decided it would be useful to have basic IF
directive support as well as allowing for argument passed to functions
(such as [% a(b) %]).  I added these features, played around with
things, toyed with tag parsing methods.  At first there was no optree
- the finished document was built as the parse progressed.  But then I
discovered that blocks and meta tags can be out of order in the
document.  It became easier to build an optree.  It was relatively
easy.  It was only 1800 lines and took about 80 hours to write.

I then tried it against the TT 2.14 test suite.  It took another 20
hours to make it pass the rest of the TT test suite.  I was done
mostly around late January 2006 - but I've been waiting for the
anticipated 2.15 release so I could make sure that the new module is
fully compliant with any of the bug fixes that have gone into TT.  I'm
still waiting - but I'm getting to the point I'd like to release the
code.

So the first big question:  Is there room for two engines that implement
the Template Toolkit specification?

Obviously there are pros and cons to releasing another module that does
the same thing that Template::Toolkit does.

Next question.  If I do release it - should I go to lengths to support all
of the extended options that TT uses?  For example, there is no support
for V1DOLLAR and there won't be.  I've also removed support for the
ANYCASE option (Increased the overall string parsing from 339% listed in the
example below to 359%.  That isn't a major increase.  And removing ANYCASE has
no effect on compiled templates at all.)

Some other options to consider removing in CET:

   - Direct access to blocks located in other templates.

   - "References"

   - PERL and RAWPERL blocks (CET doesn't use perl for execution)
     I'd still leave the eval_perl option though.

The big things missing that won't be implemented are TT2 views, and I
may or may not include the new magic TT3 provider namespaces such as
"hash:" or "file:" (etc).

Whether I release a separate module or not, the TT dev team (mostly
Andy) will be welcome to cut out what ever portions of code they may
find useful.  The CET code base is somewhat different from TT in that
TT uses a separate object for each phase of execution while CET uses a
separate method.  This makes CET either easier or harder to override
functionality depending upon which programming camp you come from.

Finally - Is releasing this premature?  Will TT3's speed increase?  Is
increasing the speed a factor for anybody else?  Does anybody even
care if there is another module?

I apologize that this letter doesn't include the source code.  I'd
rather wait until I can see the general feelings of people on the
matter.  I'm sure there will be split feelings either way.

If you have something scathing to say in response, you are certainly
welcome to.  But please decide if it is appropriate for the entire
list to hear.  Otherwise just email me directly.

Paul Seamons


///----------------------------------------------------------------///

The following three files will be sent as follow-ups to this email (the first 
time I tried I put them all in the same email and it exceeded the mailing 
list max).

7_template_00_base.t - The file used to test most of the language constructs 
of CGI::Ex::Template.  If you uncomment the line that says $module = 
'Template' it will use Template instead.  It is useful for finding edge 
cases.

bench_template.pl - Used to test relative performance.  All benchmarks should 
be taken with a grain of salt.  The output of the run on my machine is listed 
below.  The output varies depending upon memory, disk and processor speed.

perldoc - This is perldoc CGI::Ex::Template > perldoc  - It is the unfinished 
perldoc for CGI::Ex::Template.  Did I mention that it is unfinished.

///----------------------------------------------------------------///

The following results are the output of the bench_template.pl script
included in the email.  The computer used is a 1.86 Pentium M with 1
Gig of ram running Breezy Kubuntu.  All percentages are
CGI::Ex::Template vs TT2.14.  The first column shows the "template"
that is being processed.  The second column is both engines using
compiled templates that are already in memory.  For the third column
the engines use a new object each time.  In the fourth column the
engine is using file side caches (CACHE_EXT is set) (it needs to load
a new object each time).  The fifth column is passing the template as
a scalar ref rather than loading from file.  The last column is the
number of iterations per second of CET running in memory (iterations
used for determining the first column).

Copying and pasting this into a fixed width display will make things line up a 
little better.

                                                    ### All percents are 
CGI::Ex::Template vs TT2
                                                    ### (The percent that CET 
is faster than TT)
                                                          Existing object by 
string ref #
                                                 New object with CACHE_EXT set 
#        #
                                                 New object each time #        
#        #
         This percent is compiled in memory (repeated calls) #        #        
#        #
"",                                                 #  236%  #  645%  #  337%  
#  457%  # 19787.6/s #
"[% one %]",                                        #  168%  #  592%  #  421%  
#  476%  # 14355.1/s #
"[% one %]"x100,                                    #   31%  #  341%  #   79%  
#  348%  # 940.2/s #
"[% SET one = 2 %]",                                #  161%  #  534%  #  419%  
#  406%  # 14121.9/s #
"[% SET one = 2 %]"x100,                            #   12%  #  279%  #   37%  
#  276%  # 864.5/s #
"[% SET one = [0..30] %]",                          #   42%  #  320%  #  247%  
#  211%  # 7518.1/s #
"[% hash.a %]",                                     #  173%  #  619%  #  423%  
#  494%  # 13334.4/s #
"".((" "x100)."[% one %]\n")x10,                    #   82%  #  517%  #  261%  
#  476%  # 5848.1/s #
"".((" "x10)."[% one %]\n")x100,                    #   23%  #  432%  #  116%  
#  422%  # 867.7/s #
"".("[% \"".(" "x100)."\$one\" %]\n")x10,           #  -15%  #  1415%  #  102%  
#  1467%  # 2700.5/s #
"".("[% \"".(" "x10)."\$one\" %]\n")x100,           #  -50%  #  299%  #    2%  
#  302%  # 329.3/s #
"[% 2 %]",                                          #  177%  #  602%  #  459%  
#  459%  # 15838.0/s #
"[% 1 + 2 %]",                                      #   87%  #  435%  #  334%  
#  299%  # 10746.9/s #
"[% 1 + 2 + 3 + 5 + 6 + 8 %]",                      #   67%  #  320%  #  301%  
#  218%  # 9570.1/s #
"[% c.d.0.hee.0 %]",                                #  171%  #  616%  #  416%  
#  527%  # 13717.7/s #
"[% SET c.d.0.hee.0 = 2 %]",                        #  156%  #  519%  #  364%  
#  413%  # 10628.0/s #
"[% c.d.0.hee.0 %]"x100,                            #   54%  #  464%  #   82%  
#  467%  # 752.8/s #
"[% SET c.d.0.hee.0 = 2 %]"x100,                    #  107%  #  341%  #   91%  
#  341%  # 342.0/s #
"[% t = 1 || 0 ? 0 : 1 || 2 ? 2 : 3 %][% t %]",     #   73%  #  291%  #  256%  
#  210%  # 8674.9/s #
"[% a=1 %][% IF a %]Two[% END %]",                  #  126%  #  481%  #  347%  
#  378%  # 11166.3/s #
"         [% IF a %]Two[% END %]",                  #  161%  #  596%  #  412%  
#  492%  # 13846.3/s #
"[% IF a %]A[% ELSE %]B[% END %]",                  #  141%  #  526%  #  378%  
#  422%  # 12728.4/s #
"[% IF a %]A[% ELSIF b %]B[% ELSE %]C[% END %]",    #  131%  #  519%  #  359%  
#  407%  # 11386.8/s #
"[% FOREACH i = [0..10]   ; i ; END %]",            #   16%  #  230%  #  154%  
#  155%  # 2376.1/s #
"[% FOREACH i = [0..100]  ; i ; END %]",            #  -15%  #   38%  #   13%  
#   18%  # 362.5/s #
"[% FOREACH [0..10]       ; i ; END %]",            #   23%  #  245%  #  162%  
#  169%  # 2463.0/s #
"[% FOREACH [0..100]      ; i ; END %]",            #   -4%  #   56%  #   28%  
#   32%  # 384.9/s #
"[% f = 10 %][%WHILE f%][%f=f- 1%][%f%][% END %]",  #  -14%  #  152%  #   50%  
#  102%  # 1279.5/s #
"[% f = 10; WHILE (g=f) ; f = f - 1 ; f ; END %]",  #  -18%  #  115%  #   34%  
#   75%  # 1014.6/s #
"[% f = 1;  WHILE (g=f) ; f = f - 1 ; f ; END %]",  #   38%  #  302%  #  193%  
#  223%  # 5061.4/s #
"[% PROCESS bar.tt %]",                             #  236%  #  592%  #  397%  
#  506%  # 10189.6/s #
"[% INCLUDE baz.tt %]",                             #  157%  #  427%  #  296%  
#  370%  # 6549.1/s #
"[% BLOCK foo %]Hi[% END %][% PROCESS foo %]",      #  162%  #  592%  #  422%  
#  487%  # 10030.6/s #
"[% BLOCK foo %]Hi[% END %][% INCLUDE foo %]",      #  140%  #  557%  #  387%  
#  462%  # 8555.5/s #
"[% MACRO foo BLOCK %]Hi[% END %][% foo %]",        #   79%  #  413%  #  301%  
#  309%  # 7363.9/s #
"[% MACRO foo(n) BLOCK %]Hi[%n%][%END%][%foo(2)%]", #   65%  #  296%  #  265%  
#  219%  # 6081.4/s #
"[% MACRO foo PROCESS bar;BLOCK bar%]7[%END;foo%]", #   96%  #  449%  #  316%  
#  355%  # 5962.3/s #
"[% n = 1 %][% n | repeat(2) %]",                   #  128%  #  432%  #  370%  
#  336%  # 9705.7/s #
"[% n = 1 %][% n FILTER repeat(2) %]",              #   91%  #  367%  #  325%  
#  256%  # 8025.8/s #
"[% n=1; n FILTER echo=repeat(2); n FILTER echo%]", #   36%  #  317%  #  241%  
#  243%  # 5321.4/s #
"[% constants.simple %]",                           #  176%  #  617%  #  473%  
#  448%  # 15760.8/s #
"[%one='ONE'%][% PERL %]print \"[%one%]\"[%END%]",  #   66%  #  447%  #  300%  
#  357%  # 6472.9/s #
"[% 'hi' | \$filt %]",                              #   97%  #  517%  #  348%  
#  400%  # 9500.9/s #
"[% ' ' | uri %]",                                  #  127%  #  620%  #  402%  
#  505%  # 11498.0/s #
"[% foo | eval %]",                                 #  326%  #  600%  #  498%  
#  517%  # 5022.9/s #
"[% b = \\code(1); b(2) %]",                        #   60%  #  270%  #  239%  
#  174%  # 6451.9/s #
"[% foo = BLOCK %]Hi[% END %][% foo %]",            #  105%  #  438%  #  312%  
#  326%  # 9962.1/s #
"$longer_template",                                 #   51%  #  305%  #  139%  
#  264%  # 1098.6/s #
       # overall                                    #   94%  #  439%  #  268%  
#  359%  #
       # overall (with Stash::XS)                   #   27%  #  371%  #  212%  
#  307%  #

# Note that TT is faster on for loops and while loops.  The opcode tree method 
of CET can't outperform the low level loops in perl.

_______________________________________________
templates mailing list
templates@template-toolkit.org
http://lists.template-toolkit.org/mailman/listinfo/templates

Reply via email to