--- /dev/null
+
+use warnings ;
+use strict ;
+
+use Getopt::Long ;
+use Data::Dumper ;
+
+use File::Slurp ;
+
+use Benchmark qw(:hireswallclock cmpthese);
+
+my $opts = parse_options() ;
+
+my $template_info = [
+ {
+ name => 'basic',
+ data => {
+ name => 'bob',
+ },
+ expected => 'hehe bob',
+ simple => 'hehe [% name %]',
+ toolkit => 'hehe [% name %]',
+ teeny => 'hehe [% name %]',
+ },
+ {
+ name => 'nested',
+ data => {
+ title => 'Bobs Blog',
+ posts => [
+ {
+ title => 'hehe',
+ date => 'Today'
+ },
+ {
+ title => 'Something new',
+ date => '3 Days ago',
+ },
+ ],
+ },
+ expected => <<EXPECTED,
+<html>
+ <head><title>Bobs Blog</title></head>
+ <body>
+ <ul>
+ <li>
+ <h3>hehe</h3>
+ <span>Today</span>
+ </li>
+ <li>
+ <h3>Something new</h3>
+ <span>3 Days ago</span>
+ </li>
+ </ul>
+ </body>
+</html>
+EXPECTED
+
+ simple => <<SIMPLE,
+<html>
+ <head><title>[% title %]</title></head>
+ <body>
+ <ul>[% START posts %]
+ <li>
+ <h3>[% title %]</h3>
+ <span>[% date %]</span>
+ </li>[% END posts %]
+ </ul>
+ </body>
+</html>
+SIMPLE
+
+ toolkit => <<TOOLKIT,
+<html>
+ <head><title>[% title %]</title></head>
+ <body>
+ <ul>
+ [% FOREACH post = posts %]
+ <li>
+ <h3>[% post.title %]</h3>
+ <span>[% post.date %]</span>
+ </li>
+ [% END %]
+ </ul>
+ </body>
+</html>
+TOOLKIT
+
+ teeny => <<TEENY,
+<html>
+ <head><title>[% title %]</title></head>
+ <body>
+ <ul>
+ [% SECTION post %]
+ <li>
+ <h3>[% title %]</h3>
+ <span>[% date %]</span>
+ </li>
+ [% END %]
+ </ul>
+ </body>
+</html>
+TEENY
+ },
+] ;
+
+my $benches = [
+ {
+ name => 'T::S',
+ template_key => 'simple',
+ load => sub {
+ return eval { require Template::Simple } ;
+ },
+ setup => sub {
+ my( $bench, $info ) = @_ ;
+
+ my $template = $info->{$bench->{template_key}} ;
+ my $data = $info->{data} ;
+ my $name = $info->{name} ;
+
+ my $obj = Template::Simple->new(
+ templates => { $name => $template }
+ ) ;
+
+ $bench->{render} =
+ sub { $obj->render( $name, $data ) } ;
+ },
+ verify => sub {
+ my( $bench, $info ) = @_ ;
+ my $result = $bench->{render}->() ;
+ $bench->{result} = ${$result} ;
+ },
+ },
+ {
+ name => 'T::S compiled',
+ template_key => 'simple',
+ load => sub {
+ return eval { require Template::Simple } ;
+ },
+ setup => sub {
+ my( $bench, $info ) = @_ ;
+
+ my $template = $info->{$bench->{template_key}} ;
+ my $data = $info->{data} ;
+ my $name = $info->{name} ;
+
+ my $obj = Template::Simple->new(
+ templates => { $name => $template }
+ ) ;
+ $obj->compile( $name ) ;
+
+ $bench->{render} =
+ sub { $obj->render( $name, $data ) } ;
+ },
+ verify => sub {
+ my( $bench, $info ) = @_ ;
+ my $result = $bench->{render}->() ;
+ $bench->{result} = ${$result} ;
+ },
+ },
+] ;
+
+run_benchmarks() ;
+
+sub run_benchmarks {
+
+ foreach my $info ( @{$template_info} ) {
+
+ my %compares ;
+
+ foreach my $bench ( @{$benches} ) {
+
+ my $loaded = $bench->{load}->() ;
+ unless( $loaded ) {
+ print
+ "skipping $bench->{name} as it didn't load\n" ;
+ next ;
+ }
+
+ $bench->{setup}->( $bench, $info ) ;
+ $bench->{verify}->( $bench, $info ) ;
+
+ if ( $bench->{result} ne $info->{expected} ) {
+
+ print
+ "RESULT [$bench->{result}]\nEXPECTED [$info->{expected}]\n" ;
+ }
+ else {
+ print "'$bench->{name}' rendering of '$info->{name}' is verified\n" ;
+ }
+
+ $compares{ $bench->{name} } = $bench->{render} ;
+ }
+
+ cmpthese( $opts->{iterations}, \%compares ) ;
+ }
+}
+
+
+
+
+sub parse_options {
+
+ GetOptions( \my %opts,
+ 'verify|v',
+ 'iterations|i',
+ 'templaters|t',
+ 'help|?',
+ ) ;
+
+ usage( '' ) if $opts{ 'help' } ;
+
+ $opts{iterations} ||= -2 ;
+
+ $opts{templaters} = [split /,/, $opts{templaters}]
+ if $opts{templaters} ;
+
+ return \%opts ;
+}
+
+sub usage {
+
+ my $err_msg = shift || '' ;
+
+ my $usage = <<'=cut' ;
+
+bench_templates.pl - Benchmark Multiple Templaters
+
+=head1 SYNOPSIS
+
+load_menus.pl [--verify | -v] [--iterations | -i <iter>]
+ [--templaters| -t <templaters>] [--help]
+
+=head1 DESCRIPTION
+
+ --rid | -r <rids> Select the restaurant ID to be fetched.
+ Can be a comma separated list of rids.
+ 'ALL' will select all the valid
+ ID's from a source. This is
+ required (unless <source> is set
+ to 'ALL'.
+
+ [--file | -f] Load the XML from files. The file is
+
+ [--help | ?] Print this help text
+
+=cut
+
+ $usage =~ s/^=\w+.*$//mg ;
+
+ $usage =~ s/\n{2,}/\n\n/g ;
+ $usage =~ s/\A\n+// ;
+
+ die "$err_msg\n$usage" ;
+}