Commit | Line | Data |
7af713e3 |
1 | #!/usr/bin/perl |
2 | |
3 | use lib '../lib' ; |
4 | use lib 'lib' ; |
b8f7f9ec |
5 | |
6 | use warnings ; |
7 | use strict ; |
8 | |
b8f7f9ec |
9 | use Data::Dumper ; |
10 | |
7af713e3 |
11 | use Getopt::Long ; |
b8f7f9ec |
12 | use File::Slurp ; |
b8f7f9ec |
13 | use Benchmark qw(:hireswallclock cmpthese); |
14 | |
15 | my $opts = parse_options() ; |
16 | |
17 | my $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> |
59 | EXPECTED |
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> |
73 | SIMPLE |
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> |
89 | TOOLKIT |
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 |
104 | TEENY |
105 | }, |
106 | ] ; |
107 | |
108 | my $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 | |
226 | run_benchmarks() ; |
227 | |
228 | sub 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 ; |
239 | Skipping $bench->{name} as it didn't load |
240 | BAD |
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 ; |
252 | Skipping $bench->{name} as it doesn't have verified results. |
253 | RESULT [$bench->{result}]\nEXPECTED [$info->{expected}] |
254 | BAD |
255 | next ; |
256 | } |
257 | else { |
258 | print <<GOOD ; |
259 | '$bench->{name}' rendering of '$info->{name}' is verified |
260 | GOOD |
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 |
273 | sub 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 | |
292 | sub usage { |
293 | |
294 | my $err_msg = shift || '' ; |
295 | |
296 | my $usage = <<'=cut' ; |
297 | |
298 | bench_templates.pl - Benchmark Multiple Templaters |
299 | |
300 | =head1 SYNOPSIS |
301 | |
302 | load_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 | } |