Commit | Line | Data |
b8f7f9ec |
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 | } |