first version of new benchmark script
[urisagit/Template-Simple.git] / extras / bench_new.pl
1
2 use warnings ;
3 use strict ;
4
5 use Getopt::Long ;
6 use Data::Dumper ;
7
8 use File::Slurp ;
9
10 use Benchmark qw(:hireswallclock cmpthese);
11
12 my $opts = parse_options() ;
13
14 my $template_info = [
15         {
16                 name    => 'basic',
17                 data    => {
18                         name    => 'bob',
19                 },
20                 expected => 'hehe bob',
21                 simple  => 'hehe [% name %]',
22                 toolkit => 'hehe [% name %]',
23                 teeny   => 'hehe [% name %]',
24         },
25         {
26                 name    => 'nested',
27                 data    => {
28                         title   => 'Bobs Blog',
29                         posts   => [
30                                 {
31                                         title   => 'hehe',
32                                         date    => 'Today'
33                                 },
34                                 {
35                                         title   => 'Something new',
36                                         date    => '3 Days ago',
37                                 },
38                         ],
39                 },
40                 expected => <<EXPECTED,
41 <html>
42   <head><title>Bobs Blog</title></head>
43   <body>
44     <ul>
45         <li>
46             <h3>hehe</h3>
47             <span>Today</span>
48         </li>
49         <li>
50             <h3>Something new</h3>
51             <span>3 Days ago</span>
52         </li>
53     </ul>
54   </body>
55 </html>
56 EXPECTED
57
58                 simple  => <<SIMPLE,
59 <html>
60   <head><title>[% title %]</title></head>
61   <body>
62     <ul>[% START posts %]
63         <li>
64             <h3>[% title %]</h3>
65             <span>[% date %]</span>
66         </li>[% END posts %]
67     </ul>
68   </body>
69 </html>
70 SIMPLE
71
72                 toolkit => <<TOOLKIT,
73 <html>
74   <head><title>[% title %]</title></head>
75   <body>
76     <ul>
77       [% FOREACH post = posts %]
78         <li>
79             <h3>[% post.title %]</h3>
80             <span>[% post.date %]</span>
81         </li>
82       [% END %]
83     </ul>
84   </body>
85 </html>
86 TOOLKIT
87
88                 teeny   => <<TEENY,
89 <html>
90   <head><title>[% title %]</title></head>
91   <body>
92     <ul>
93       [% SECTION post %]
94         <li>
95             <h3>[% title %]</h3>
96             <span>[% date %]</span>
97         </li>
98       [% END %]
99     </ul>
100   </body>
101 </html>
102 TEENY
103         },
104 ] ;
105
106 my $benches = [
107         {
108                 name    => 'T::S',
109                 template_key => 'simple',
110                 load    => sub {
111                         return eval { require Template::Simple } ;
112                 },
113                 setup   => sub {
114                         my( $bench, $info ) = @_ ;
115
116                         my $template = $info->{$bench->{template_key}} ;
117                         my $data = $info->{data} ;
118                         my $name = $info->{name} ;
119
120                         my $obj = Template::Simple->new(
121                                 templates => { $name => $template }
122                         ) ;
123
124                         $bench->{render} =
125                                 sub { $obj->render( $name, $data ) } ;
126                 },
127                 verify  => sub {
128                         my( $bench, $info ) = @_ ;
129                         my $result = $bench->{render}->() ;
130                         $bench->{result} = ${$result} ;
131                 },
132         },
133         {
134                 name    => 'T::S compiled',
135                 template_key => 'simple',
136                 load    => sub {
137                         return eval { require Template::Simple } ;
138                 },
139                 setup   => sub {
140                         my( $bench, $info ) = @_ ;
141
142                         my $template = $info->{$bench->{template_key}} ;
143                         my $data = $info->{data} ;
144                         my $name = $info->{name} ;
145
146                         my $obj = Template::Simple->new(
147                                 templates => { $name => $template }
148                         ) ;
149                         $obj->compile( $name ) ;
150
151                         $bench->{render} =
152                                 sub { $obj->render( $name, $data ) } ;
153                 },
154                 verify  => sub {
155                         my( $bench, $info ) = @_ ;
156                         my $result = $bench->{render}->() ;
157                         $bench->{result} = ${$result} ;
158                 },
159         },
160 ] ;
161
162 run_benchmarks() ;
163
164 sub run_benchmarks {
165
166         foreach my $info ( @{$template_info} ) {
167
168                 my %compares ;
169
170                 foreach my $bench ( @{$benches} ) {
171
172                         my $loaded = $bench->{load}->() ;
173                         unless( $loaded ) {
174                                 print
175                                 "skipping $bench->{name} as it didn't load\n" ;
176                                 next ;
177                         }
178
179                         $bench->{setup}->( $bench, $info ) ;
180                         $bench->{verify}->( $bench, $info ) ;
181
182                         if ( $bench->{result} ne $info->{expected} ) {
183
184                                 print
185                 "RESULT [$bench->{result}]\nEXPECTED [$info->{expected}]\n" ;
186                         }
187                         else {
188         print "'$bench->{name}' rendering of '$info->{name}' is verified\n" ;
189                         }
190
191                         $compares{ $bench->{name} } = $bench->{render} ;
192                 }
193
194                 cmpthese( $opts->{iterations}, \%compares ) ;
195         }
196 }
197
198
199
200
201 sub parse_options {
202
203         GetOptions( \my %opts,
204                 'verify|v',
205                 'iterations|i',
206                 'templaters|t',
207                 'help|?',
208         ) ;
209
210         usage( '' ) if $opts{ 'help' } ;
211
212         $opts{iterations} ||= -2 ;
213
214         $opts{templaters} = [split /,/, $opts{templaters}]
215                 if $opts{templaters} ;
216
217         return \%opts ;
218 }
219
220 sub usage {
221
222         my $err_msg = shift || '' ;
223
224         my $usage = <<'=cut' ;
225
226 bench_templates.pl - Benchmark Multiple Templaters
227
228 =head1 SYNOPSIS
229
230 load_menus.pl [--verify | -v] [--iterations | -i <iter>]
231         [--templaters| -t <templaters>] [--help]
232
233 =head1 DESCRIPTION
234
235         --rid | -r <rids>               Select the restaurant ID to be fetched.
236                                         Can be a comma separated list of rids. 
237                                         'ALL' will select all the valid
238                                         ID's from a source. This is
239                                         required (unless <source> is set
240                                         to 'ALL'.
241
242         [--file | -f]                   Load the XML from files. The file is
243
244         [--help | ?]                    Print this help text
245
246 =cut
247
248         $usage =~ s/^=\w+.*$//mg ;
249
250         $usage =~ s/\n{2,}/\n\n/g ;
251         $usage =~ s/\A\n+// ;
252
253         die "$err_msg\n$usage" ;
254 }