added support for template::teeny
[urisagit/Template-Simple.git] / extras / bench_new.pl
CommitLineData
7af713e3 1#!/usr/bin/perl
2
3use lib '../lib' ;
4use lib 'lib' ;
b8f7f9ec 5
6use warnings ;
7use strict ;
8
b8f7f9ec 9use Data::Dumper ;
10
7af713e3 11use Getopt::Long ;
b8f7f9ec 12use File::Slurp ;
b8f7f9ec 13use Benchmark qw(:hireswallclock cmpthese);
14
15my $opts = parse_options() ;
16
17my $template_info = [
18 {
19 name => 'basic',
20 data => {
21 name => 'bob',
22 },
23 expected => 'hehe bob',
24 simple => 'hehe [% name %]',
25 toolkit => 'hehe [% name %]',
26 teeny => 'hehe [% name %]',
27 },
28 {
29 name => 'nested',
30 data => {
31 title => 'Bobs Blog',
32 posts => [
33 {
34 title => 'hehe',
35 date => 'Today'
36 },
37 {
38 title => 'Something new',
39 date => '3 Days ago',
40 },
41 ],
42 },
43 expected => <<EXPECTED,
44<html>
45 <head><title>Bobs Blog</title></head>
46 <body>
47 <ul>
48 <li>
49 <h3>hehe</h3>
50 <span>Today</span>
51 </li>
52 <li>
53 <h3>Something new</h3>
54 <span>3 Days ago</span>
55 </li>
56 </ul>
57 </body>
58</html>
59EXPECTED
60
61 simple => <<SIMPLE,
62<html>
63 <head><title>[% title %]</title></head>
64 <body>
65 <ul>[% START posts %]
66 <li>
67 <h3>[% title %]</h3>
68 <span>[% date %]</span>
69 </li>[% END posts %]
70 </ul>
71 </body>
72</html>
73SIMPLE
74
75 toolkit => <<TOOLKIT,
76<html>
77 <head><title>[% title %]</title></head>
78 <body>
79 <ul>
80 [% FOREACH post = posts %]
81 <li>
82 <h3>[% post.title %]</h3>
83 <span>[% post.date %]</span>
84 </li>
85 [% END %]
86 </ul>
87 </body>
88</html>
89TOOLKIT
90
91 teeny => <<TEENY,
92<html>
93 <head><title>[% title %]</title></head>
94 <body>
7af713e3 95 <ul>[% SECTION post %]
b8f7f9ec 96 <li>
97 <h3>[% title %]</h3>
98 <span>[% date %]</span>
7af713e3 99 </li>[% END %]
b8f7f9ec 100 </ul>
101 </body>
102</html>
7af713e3 103
b8f7f9ec 104TEENY
105 },
106] ;
107
108my $benches = [
109 {
110 name => 'T::S',
111 template_key => 'simple',
112 load => sub {
113 return eval { require Template::Simple } ;
114 },
115 setup => sub {
116 my( $bench, $info ) = @_ ;
117
118 my $template = $info->{$bench->{template_key}} ;
119 my $data = $info->{data} ;
120 my $name = $info->{name} ;
121
122 my $obj = Template::Simple->new(
123 templates => { $name => $template }
124 ) ;
125
126 $bench->{render} =
127 sub { $obj->render( $name, $data ) } ;
128 },
129 verify => sub {
130 my( $bench, $info ) = @_ ;
131 my $result = $bench->{render}->() ;
132 $bench->{result} = ${$result} ;
133 },
134 },
135 {
136 name => 'T::S compiled',
137 template_key => 'simple',
138 load => sub {
139 return eval { require Template::Simple } ;
140 },
141 setup => sub {
142 my( $bench, $info ) = @_ ;
143
144 my $template = $info->{$bench->{template_key}} ;
145 my $data = $info->{data} ;
146 my $name = $info->{name} ;
147
148 my $obj = Template::Simple->new(
149 templates => { $name => $template }
150 ) ;
151 $obj->compile( $name ) ;
152
153 $bench->{render} =
154 sub { $obj->render( $name, $data ) } ;
155 },
156 verify => sub {
157 my( $bench, $info ) = @_ ;
158 my $result = $bench->{render}->() ;
159 $bench->{result} = ${$result} ;
160 },
161 },
7af713e3 162 {
163 name => 'Teeny',
164 template_key => 'teeny',
165 load => sub {
166 return eval {
167 require Template::Teeny ;
168 require Template::Teeny::Stash ;
169 } ;
170 },
171 setup => sub {
172 my( $bench, $info ) = @_ ;
173
174 my $template = $info->{$bench->{template_key}} ;
175 my $data = $info->{data} ;
176 my $name = $info->{name} ;
177
178 my $results ;
179 open my $fh, '>', \$results or
180 die "can't open string for output" ;
181
182 mkdir 'tpl' ;
183 write_file( "tpl/$name.tpl", $template ) ;
184 my $obj = Template::Teeny->new(
185 { include_path => ['tpl'] }
186 ) ;
187
188 my $stash ;
189 if ( my $posts = $data->{posts} ) {
190
191 $stash = Template::Teeny::Stash->new(
192 { title => $data->{title} }
193 ) ;
194
195 foreach my $post ( @{$posts} ) {
196
197 my $substash =
198 Template::Teeny::Stash->new(
199 $post
200 ) ;
201 $stash->add_section('post', $substash );
202 }
203 }
204 else {
205 $stash = Template::Teeny::Stash->new(
206 $data
207 ) ;
208
209 }
210
211#print Dumper $stash ;
212 $bench->{render} =
213 sub {
214 $obj->process("$name.tpl", $stash, $fh );
215 $bench->{result} = $results ;
216 }
217
218 },
219 verify => sub {
220 my( $bench, $info ) = @_ ;
221 $bench->{result} = $bench->{render}->() ;
222 },
223 },
b8f7f9ec 224] ;
225
226run_benchmarks() ;
227
228sub run_benchmarks {
229
230 foreach my $info ( @{$template_info} ) {
231
232 my %compares ;
233
234 foreach my $bench ( @{$benches} ) {
235
236 my $loaded = $bench->{load}->() ;
237 unless( $loaded ) {
7af713e3 238 print <<BAD ;
239Skipping $bench->{name} as it didn't load
240BAD
b8f7f9ec 241 next ;
242 }
243
244 $bench->{setup}->( $bench, $info ) ;
b8f7f9ec 245
7af713e3 246 if ( $opts->{verify} ) {
247 $bench->{verify}->( $bench, $info ) ;
248
249 if ( $bench->{result} ne $info->{expected} ) {
250
251 print <<BAD ;
252Skipping $bench->{name} as it doesn't have verified results.
253RESULT [$bench->{result}]\nEXPECTED [$info->{expected}]
254BAD
255 next ;
256 }
257 else {
258 print <<GOOD ;
259'$bench->{name}' rendering of '$info->{name}' is verified
260GOOD
261 }
b8f7f9ec 262 }
263
264 $compares{ $bench->{name} } = $bench->{render} ;
265 }
266
7af713e3 267 print "\nBenchmark of '$info->{name}' template\n" ;
b8f7f9ec 268 cmpthese( $opts->{iterations}, \%compares ) ;
7af713e3 269 print "\n" ;
b8f7f9ec 270 }
271}
272
b8f7f9ec 273sub parse_options {
274
275 GetOptions( \my %opts,
276 'verify|v',
277 'iterations|i',
278 'templaters|t',
279 'help|?',
280 ) ;
281
282 usage( '' ) if $opts{ 'help' } ;
283
284 $opts{iterations} ||= -2 ;
285
286 $opts{templaters} = [split /,/, $opts{templaters}]
287 if $opts{templaters} ;
288
289 return \%opts ;
290}
291
292sub usage {
293
294 my $err_msg = shift || '' ;
295
296 my $usage = <<'=cut' ;
297
298bench_templates.pl - Benchmark Multiple Templaters
299
300=head1 SYNOPSIS
301
302load_menus.pl [--verify | -v] [--iterations | -i <iter>]
303 [--templaters| -t <templaters>] [--help]
304
305=head1 DESCRIPTION
306
307 --rid | -r <rids> Select the restaurant ID to be fetched.
308 Can be a comma separated list of rids.
309 'ALL' will select all the valid
310 ID's from a source. This is
311 required (unless <source> is set
312 to 'ALL'.
313
314 [--file | -f] Load the XML from files. The file is
315
316 [--help | ?] Print this help text
317
318=cut
319
320 $usage =~ s/^=\w+.*$//mg ;
321
322 $usage =~ s/\n{2,}/\n\n/g ;
323 $usage =~ s/\A\n+// ;
324
325 die "$err_msg\n$usage" ;
326}