On 25/06/07, Tobias Kremer <[EMAIL PROTECTED]> wrote:
(widget) timethis 1000: 7 wallclock secs ( 7.26 usr + 0.35 sys = 7.61 CPU) @ 131.41/s (n=1000) (formfu) timethis 1000: 63 wallclock secs (59.00 usr + 2.99 sys = 61.99 CPU) @ 16.13/s (n=1000)
Okay, I've done some testing, and here's the results so far - and I believe I have some good news! I used 2 different benchmark files, both compare equivalent forms built using HTML::FormFu, CGI::FormBuilder and HTML::Widget. The first, "benchmark-basic.pl" has 10 text fields (each with the 'size' attribute set), and a submit button. The second, "benchmark.pl", is similar, but has a select field containing 101 items, and also the 'label' and 'value' set for all the fields. INITIAL BENCHMARKS benchmark-basic.pl * FormBuilder was 3x faster than FormFu * html-widget was 15x faster than FormFu benchmark.pl * FormBuilder was 3.2x faster than FormFu * html-widget was 7x faster than FormFu This shows... * html-widget is significantly faster than formfu * html-widget has the biggest slowdown for the test using a large select field (see below for benchmark output and files). INLINED TEMPLATES BENCHMARK I then experimented with inlining the FormFu TT templates, removing all uses of WRAPPER, and as many uses of INCLUDE as possible. In the end the only remaining includes were for block elements - so the form used a single include for the fieldset, then the fieldset had an include for each field. (so that's a total of 12 includes for benchmark-basic.pl, and 13 includes for benchmark.pl) benchmark-basic.pl * FormBuilder was 2.3x faster than FormFu * html-widget was 11.5x faster than FormFu benchmark.pl * FormBuilder was 2.2x faster than FormFu * html-widget was 4.7x faster than FormFu This shows... * significant speed-up * still a lot slower than html-widget However there is a significant loss in functionality (losing a lot of the granularity from the templates). Template::Alloy BENCHMARK I then reverted these changes and swapped from using TT to Template::Alloy which supports the TT syntax and claims to be faster. I only came across 1 incompatibility when running the FormFu test suite - I was able to work around the problem with a minor change to the templates, and I've logged a bug report with RT about it. benchmark-basic.pl * FormBuilder was 1.6x faster than FormFu * html-widget was 8.2x faster than FormFu benchmark.pl * FormBuilder was 2.1x faster than FormFu * html-widget was 4.5x faster than FormFu This shows... * massive speed difference simply switching to from TT to Template::Alloy * still a noticeable slow-down when using a large select field - this is likely due to the template include for every option in the select field Template::Alloy + INLINED SELECT OPTION BENCHMARK I then also inlined the select option template - this was only in a separate template for code-reuse reasons, not for user-customisation - so I don't mind removing it. benchmark-basic.pl * FormBuilder was 1.5x faster than FormFu * html-widget was 8x faster than FormFu benchmark.pl * FormBuilder was 1.6x faster than FormFu * html-widget was 3.5x faster than FormFu This shows... * another significant speed-up when using a large select field CONCLUSIONS I plan to check-in the inlining of the select option template (and the same change for radiogroup items) to remove the hit when rendering large select fields. I plan to make FormFu configurable, so you can easily choose (preferably in your config file) to use Template::Alloy instead of TT. The Template::Alloy TT incompatibility mentioned above was specific to the select/radiogroup template which I propose removing - so it isn't even an issue for use any more. It would be good to have benchmark scripts in the repository which compare several real-world templates, and possibly another which intensively uses all the standard form fields. DETAILED RESULTS ##### # benchmark 1 $ benchmark-basic.pl Rate HTML::FormFu CGI::FormBuilder HTML::Widget HTML::FormFu 17.0/s -- -67% -94% CGI::FormBuilder 51.1/s 200% -- -81% HTML::Widget 263/s 1447% 415% -- $ benchmark.pl Rate HTML::FormFu CGI::FormBuilder HTML::Widget HTML::FormFu 8.44/s -- -69% -86% CGI::FormBuilder 27.2/s 222% -- -54% HTML::Widget 59.0/s 600% 117% -- ##### # benchmark 2 # inlined templates $ benchmark-basic.pl Rate HTML::FormFu CGI::FormBuilder HTML::Widget HTML::FormFu 22.7/s -- -56% -91% CGI::FormBuilder 51.3/s 125% -- -80% HTML::Widget 262/s 1051% 410% -- $ benchmark.pl Rate HTML::FormFu CGI::FormBuilder HTML::Widget HTML::FormFu 12.3/s -- -55% -79% CGI::FormBuilder 27.0/s 120% -- -53% HTML::Widget 57.6/s 370% 114% -- ##### # benchmark 3 # Template::Alloy $ benchmark-basic.pl Rate HTML::FormFu CGI::FormBuilder HTML::Widget HTML::FormFu 31.5/s -- -36% -88% CGI::FormBuilder 49.1/s 56% -- -81% HTML::Widget 259/s 723% 427% -- $ benchmark.pl Rate HTML::FormFu CGI::FormBuilder HTML::Widget HTML::FormFu 13.0/s -- -52% -78% CGI::FormBuilder 27.2/s 110% -- -53% HTML::Widget 58.1/s 348% 113% -- ##### # benchmark 4 # Template::Alloy + inlined select option template $ benchmark-basic.pl Rate HTML::FormFu CGI::FormBuilder HTML::Widget HTML::FormFu 32.0/s -- -36% -88% CGI::FormBuilder 50.2/s 57% -- -80% HTML::Widget 256/s 701% 411% -- $ benchmark.pl Rate HTML::FormFu CGI::FormBuilder HTML::Widget HTML::FormFu 16.6/s -- -39% -71% CGI::FormBuilder 27.2/s 64% -- -53% HTML::Widget 58.2/s 250% 114% -- ##### # benchmark-basic.pl #!/usr/bin/perl use strict; use warnings; use lib 'lib'; use HTML::FormFu; use HTML::Widget; use CGI::FormBuilder; use Benchmark qw( cmpthese ); my $formfu = formfu(); my $widget = widget(); my $builder = builder(); # make sure TT has loaded/cached everything my $output = "$formfu"; cmpthese( 1000, { 'HTML::FormFu' => sub { $output = "$formfu"; }, 'HTML::Widget' => sub { $output = $widget->process->as_xml; }, 'CGI::FormBuilder' => sub { $output = $builder->render; }, } ); sub formfu { my $form = HTML::FormFu->new; $form->auto_fieldset(1); for (1..10) { $form->element({ name => "text$_", size => 10 }); } $form->element({ type => "submit", name => "submit", }); return $form; } sub widget { my $form = HTML::Widget->new; for (1..10) { $form->element( "Textfield", "text$_" )->size(10); } $form->element( "Submit", "submit" ); return $form; } sub builder { my $form = CGI::FormBuilder->new; for (1..10) { $form->field( name => "text$_", size => 10 ); } return $form; } ##### # benchmark.pl #!/usr/bin/perl use strict; use warnings; use lib 'lib'; use HTML::FormFu; use HTML::Widget; use CGI::FormBuilder; use Benchmark qw( cmpthese ); my $formfu = formfu(); my $widget = widget(); my $builder = builder(); # make sure TT has loaded/cached everything my $output = "$formfu"; cmpthese( 500, { 'HTML::FormFu' => sub { $output = "$formfu"; }, 'HTML::Widget' => sub { $output = $widget->process->as_xml; }, 'CGI::FormBuilder' => sub { $output = $builder->render; }, } ); sub formfu { my $form = HTML::FormFu->new; $form->auto_fieldset(1); for (1..10) { $form->element({ name => "text$_", size => 10, label => "text & $_", }); } $form->element({ name => "select", type => "select", label => "select", values => [ 1907 .. 2007 ], default => 2007, }); $form->element({ type => "submit", name => "submit", }); return $form; } sub widget { my $form = HTML::Widget->new; for (1..10) { $form->element( "Textfield", "text$_" )->label("text & $_")->size(10); } $form->element( "Select", "select" )->label("select")->options( map { $_, $_ } 1907 .. 2007 )->selected(2007); $form->element( "Submit", "submit" ); return $form; } sub builder { my $form = CGI::FormBuilder->new; for (1..10) { $form->field( name => "text$_", size => 10, label => "text & $_", ); } $form->field( name => "select", options => [ 1907 .. 2007 ], value => 2007, ); return $form; } _______________________________________________ HTML-FormFu mailing list HTML-FormFu@lists.scsys.co.uk http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu