hand edited concat (current compiler generated code) to benchmark with
Uri Guttman [Fri, 19 Dec 2008 05:53:19 +0000 (00:53 -0500)]
joined, and then append to sub var styles.

append is the fastest for sure.

bench.pl

index 2583947..c8b289f 100644 (file)
--- a/bench.pl
+++ b/bench.pl
@@ -4,61 +4,158 @@ use strict ;
 use warnings ;
 
 use Template::Simple ;
+use Benchmark qw( timethese ) ;
 use Data::Dumper ;
 
-my $data = generate_data( 3, 6 ) ;
+my @dims = @ARGV ? @ARGV : ( 3, 6 ) ;
+
+my $data = generate_data( @dims ) ;
 #print Dumper $data ;
 
 my $tmpl = Template::Simple->new() ;
 
-$tmpl->add_templates( { bench => <<TMPL } ) ;
+my $template = <<TMPL ;
 Header
 Val 1: [%val_1%]
-Val 2: [%val_2%]
-Footer
-TMPL
-
-my $x = <<XXX ;
 [%START nest%]
        Level: [%level%]
 [%END nest%]
 [%START opt%]
        Optional Level: [%level%]
 [%END opt%]
-XXX
+Val 2: [%val_2%]
+Footer
+TMPL
 
+$tmpl->add_templates( { bench => $template } ) ;
 
+my $x = <<XXX ;
+XXX
 
 my $rendered = $tmpl->render( 'bench', $data ) ;
 
-$tmpl->compile( 'bench', $data ) ;
-print $tmpl->get_source( 'bench' ) ;
+#$tmpl->compile( 'bench', $data ) ;
+#print $tmpl->get_source( 'bench' ) ;
+#my $comp_rendered = $tmpl->render( 'bench', $data ) ;
+#my $ok = $$rendered eq $$comp_rendered ;
 
-my $comp_rendered = $tmpl->render( 'bench', $data ) ;
+my $joined = joined( $data ) ;
+my $appended = joined( $data ) ;
 
-my $ok = $$rendered eq $$comp_rendered ;
+my $ok = $$rendered eq $$appended ;
 
 print "OK [$ok]\n" ;
 
-print $$rendered ;
-print $$comp_rendered ;
+# print $$rendered ;
+# print "----\n" ;
+# print $$joined ;
+#print $$comp_rendered ;
+
+timethese( shift || -2,
+       {
+               render  => sub { my $x = $tmpl->render( 'bench', $data ) },
+               joined  => sub { my $x = joined( $data ) },
+               concat  => sub { my $x = concat( $data ) },
+               append  => sub { my $x = append( $data ) },
+       }
+) ;
 
 exit ;
 
+no warnings ;
+
+
+sub rendered {
 
+}
 
+sub joined {
 
 no warnings ;
 
+       my( $data ) = @_ ;
 
-sub rendered {
+       my $out = do {
+               my $out ;
 
-}
+               my @data = $data ;
+               while( defined( my $data = shift @data ) ) {
+
+                       if ( ref $data eq 'ARRAY' ) {
+                               push @data, @{$data} ;
+                               next ;
+                       }
+
+                       $out .= ref $data ne 'HASH' ? $data :
+
+                       join( '',
+                       "Header\nVal 1: "
+                       ,
+                       $data->{val_1}
+                       ,
+                       "\n"
+                       ,
+                       do {
+                               my $data = $data->{nest} ;
+                               my $out ;
+
+                               my @data = $data ;
+                               while( defined( my $data = shift @data ) ) {
+
+                                       if ( ref $data eq 'ARRAY' ) {
+                                               push @data, @{$data} ;
+                                               next ;
+                                       }
+
+                                       $out .= ref $data ne 'HASH' ? $data :
+                                       join( '',
+                                       "\n\tLevel: "
+                                       ,
+                                       $data->{level}
+                                       ,
+                                       "\n" ) ;
+                               }
+                               $out ;
+                       }
+                       ,
+                       "\n"
+                       ,
+                       do {
+                               my $data = $data->{opt} ;
+                               my $out ;
+
+                               my @data = $data ;
+                               while( defined( my $data = shift @data ) ) {
+
+                                       if ( ref $data eq 'ARRAY' ) {
+                                               push @data, @{$data} ;
+                                               next ;
+                                       }
 
-sub map_join {
+                                       $out .= ref $data ne 'HASH' ? $data :
+                                       join( '', 
+                                       "\n\tOptional Level: "
+                                       ,
+                                       $data->{level}
+                                       ,
+                                       "\n" ) ;
+                               }
+                               $out ;
+                       }
+                       ,
+                       "\nVal 2: "
+                       ,
+                       $data->{val_2}
+                       ,
+                       "\nFooter\n" ) ;
+               }
+               $out ;
+       } ;
 
+       return \$out ;
 }
 
+
 sub append {
 
 }
@@ -66,34 +163,79 @@ sub append {
 
 sub concat {
 
+no warnings ;
+
        my( $data ) = @_ ;
 
        my $out = do {
                my $out ;
-               foreach my $data ( ref $data eq 'ARRAY' ? @{$data} : $data ) {
+
+               my @data = $data ;
+               while( defined( my $data = shift @data ) ) {
+
+                       if ( ref $data eq 'ARRAY' ) {
+                               push @data, @{$data} ;
+                               next ;
+                       }
 
                        $out .= ref $data ne 'HASH' ? $data :
-                       "text1\n"
+                       "Header\nVal 1: "
+                       .
+                       $data->{val_1}
+                       .
+                       "\n"
                        .
                        do {
                                my $data = $data->{nest} ;
-
                                my $out ;
-                               foreach my $data ( ref $data eq 'ARRAY' ? @{$data} : $data ) {
+
+                               my @data = $data ;
+                               while( defined( my $data = shift @data ) ) {
+
+                                       if ( ref $data eq 'ARRAY' ) {
+                                               push @data, @{$data} ;
+                                               next ;
+                                       }
 
                                        $out .= ref $data ne 'HASH' ? $data :
-                                       "\n\tBAR is "
+                                       "\n\tLevel: "
                                        .
-                                       $data->{bar}
+                                       $data->{level}
                                        .
                                        "\n" ;
                                }
+                               $out ;
+                       }
+                       .
+                       "\n"
+                       .
+                       do {
+                               my $data = $data->{opt} ;
+                               my $out ;
 
+                               my @data = $data ;
+                               while( defined( my $data = shift @data ) ) {
 
+                                       if ( ref $data eq 'ARRAY' ) {
+                                               push @data, @{$data} ;
+                                               next ;
+                                       }
+
+                                       $out .= ref $data ne 'HASH' ? $data :
+                                       "\n\tOptional Level: "
+                                       .
+                                       $data->{level}
+                                       .
+                                       "\n" ;
+                               }
                                $out ;
                        }
                        .
-                       "\n" ;
+                       "\nVal 2: "
+                       .
+                       $data->{val_2}
+                       .
+                       "\nFooter\n" ;
                }
                $out ;
        } ;
@@ -101,6 +243,75 @@ sub concat {
        return \$out ;
 }
 
+sub append {
+
+no warnings ;
+
+       my( $data ) = @_ ;
+
+       my $out ;
+
+       my @data = $data ;
+       while( defined( my $data = shift @data ) ) {
+
+               if ( ref $data eq 'ARRAY' ) {
+                       push @data, @{$data} ;
+                       next ;
+               }
+
+               $out .= ref $data ne 'HASH' ? $data :
+               "Header\nVal 1: "
+               .
+               $data->{val_1}
+               .
+               "\n" ;
+
+               my @data = $data->{nest} ;
+               while( defined( my $data = shift @data ) ) {
+
+                       if ( ref $data eq 'ARRAY' ) {
+                               push @data, @{$data} ;
+                               next ;
+                       }
+
+                       $out .= ref $data ne 'HASH' ? $data :
+                       "\n\tLevel: "
+                       .
+                       $data->{level}
+                       .
+                       "\n" ;
+               }
+
+               $out .=
+               "\n" ;
+
+               my @data = $data->{opt} ;
+               while( defined( my $data = shift @data ) ) {
+
+                       if ( ref $data eq 'ARRAY' ) {
+                               push @data, @{$data} ;
+                               next ;
+                       }
+
+                       $out .= ref $data ne 'HASH' ? $data :
+                       "\n\tOptional Level: "
+                       .
+                       $data->{level}
+                       .
+                       "\n" ;
+               }
+
+               $out .=
+               "\nVal 2: "
+               .
+               $data->{val_2}
+               .
+               "\nFooter\n" ;
+       }
+
+       return \$out ;
+}
+
 
 sub generate_data {