]> git.wincent.com - wikitext.git/blob - benchmarks/profile_parsing.rb
Update parsing benchmark input/output
[wikitext.git] / benchmarks / profile_parsing.rb
1 #!/usr/bin/env ruby
2 # Copyright 2008-2013 Wincent Colaiuta. All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are met:
6 #
7 # 1. Redistributions of source code must retain the above copyright notice,
8 #    this list of conditions and the following disclaimer.
9 # 2. Redistributions in binary form must reproduce the above copyright notice,
10 #    this list of conditions and the following disclaimer in the documentation
11 #    and/or other materials provided with the distribution.
12
13 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
17 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 # POSSIBILITY OF SUCH DAMAGE.
24
25 require File.join(File.dirname(__FILE__), '..', 'ext', 'wikitext')
26 require 'benchmark'
27
28 # 91 characters, 91 bytes
29 short_slab_of_ASCII_text  = '* Lorem [[ipsum|hello]] dolor sit amet, `consectetuer` http://example.com/ adipiscing elit.'
30
31 # compare against the expected output to ensure correctness
32 short_slab_of_ASCII_text_output = <<SLAB
33 <ul>
34   <li>Lorem <a href="/wiki/ipsum">hello</a> dolor sit amet, <tt>consectetuer</tt> <a href="http://example.com/" class="external">http://example.com/</a> adipiscing elit.</li>
35 </ul>
36 SLAB
37
38 # 91 characters, 122 bytes
39 short_slab_of_UTF8_text   = '* Lór€m [[ïpsûm|h€llö]] dólór sït àm€t, `cóñs€ct€tû€r` http://example.com/ àdïpïscïñg €lït.'
40
41 short_slab_of_UTF8_text_output = <<SLAB
42 <ul>
43   <li>L&#x00f3;r&#x20ac;m <a href="/wiki/%c3%afps%c3%bbm">h&#x20ac;ll&#x00f6;</a> d&#x00f3;l&#x00f3;r s&#x00ef;t &#x00e0;m&#x20ac;t, <tt>c&#x00f3;&#x00f1;s&#x20ac;ct&#x20ac;t&#x00fb;&#x20ac;r</tt> <a href="http://example.com/" class="external">http://example.com/</a> &#x00e0;d&#x00ef;p&#x00ef;sc&#x00ef;&#x00f1;g &#x20ac;l&#x00ef;t.</li>
44 </ul>
45 SLAB
46
47 # 1415 characters, 1415 bytes
48 longer_slab_of_ASCII_text = <<SLAB
49 paragraph
50 second line
51
52 new paragraph
53
54 = a heading =
55
56 > a blockquote
57 > second line of blockquote
58 >
59 > new paragraph within blockquote
60
61 == another heading ==
62
63 paragraph within ''multiple '''styles''''' and <tt>tt span</tt>
64
65 similar, but with '''styles in ''different'' order'''
66
67 again, a '''different ''order'''''
68
69 * list item 1
70 ** nested list item 1
71 ** nested list item 2
72 ** nested list item 3
73 * list item 2
74
75  // this is a code block
76  notice how it can contain ''markup''
77  which would '''otherwise''' have <tt>special</tt> meaning
78  although explicit entities &copy; are passed through unchanged
79
80 a normal paragraph again
81
82 This is where we show a link to an article on [[GCC]].
83 Related to that, [[GCC|a link]] to the same
84 article but with custom link text.
85
86 External links [http://example.com work too].
87 As well as autolinks as seen http://example.com/
88 here.
89
90 Look at how we handle bad syntax. [[This is an unterminated
91 link. And [http://example.com/ is another.
92
93 # this is an ordered list
94 # which continues
95 ## and has another ordered list
96 ## nested inside it
97 # and then falls back
98 #* and then nests another list
99 #* this time an unordered one
100 #** itself containing a nested list
101 #** which continues
102 #**# and finally nests yet another ordered list
103 #**# which continues
104 #* drops back quite a way
105 # and finally all the way
106 #****** and finishes with an invalid item
107
108 === heading with missing closing tag
109 * list
110 # new list
111 SLAB
112
113 longer_slab_of_ASCII_text_output = <<SLAB
114 <p>paragraph second line</p>
115 <p>new paragraph</p>
116 <h1>a heading</h1>
117 <blockquote>
118   <p>a blockquote second line of blockquote</p>
119   <p>new paragraph within blockquote</p>
120 </blockquote>
121 <h2>another heading</h2>
122 <p>paragraph within <em>multiple <strong>styles</strong></em> and <tt>tt span</tt></p>
123 <p>similar, but with <strong>styles in <em>different</em> order</strong></p>
124 <p>again, a <strong>different <em>order</em></strong></p>
125 <ul>
126   <li>list item 1
127     <ul>
128       <li>nested list item 1</li>
129       <li>nested list item 2</li>
130       <li>nested list item 3</li>
131     </ul>
132   </li>
133   <li>list item 2</li>
134 </ul>
135 <pre>// this is a code block
136 notice how it can contain ''markup''
137 which would '''otherwise''' have &lt;tt&gt;special&lt;/tt&gt; meaning
138 although explicit entities &copy; are passed through unchanged</pre>
139 <p>a normal paragraph again</p>
140 <p>This is where we show a link to an article on <a href="/wiki/GCC">GCC</a>. Related to that, <a href="/wiki/GCC">a link</a> to the same article but with custom link text.</p>
141 <p>External links <a href="http://example.com" class="external">work too</a>. As well as autolinks as seen <a href="http://example.com/" class="external">http://example.com/</a> here.</p>
142 <p>Look at how we handle bad syntax. [[This is an unterminated link. And [<a href="http://example.com/" class="external">http://example.com/</a> is another.</p>
143 <ol>
144   <li>this is an ordered list</li>
145   <li>which continues
146     <ol>
147       <li>and has another ordered list</li>
148       <li>nested inside it</li>
149     </ol>
150   </li>
151   <li>and then falls back
152     <ul>
153       <li>and then nests another list</li>
154       <li>this time an unordered one
155         <ul>
156           <li>itself containing a nested list</li>
157           <li>which continues
158             <ol>
159               <li>and finally nests yet another ordered list</li>
160               <li>which continues</li>
161             </ol>
162           </li>
163         </ul>
164       </li>
165       <li>drops back quite a way</li>
166     </ul>
167   </li>
168   <li>and finally all the way
169     <ul>
170       <li>***** and finishes with an invalid item</li>
171     </ul>
172   </li>
173 </ol>
174 <h3>heading with missing closing tag</h3>
175 <ul>
176   <li>list</li>
177 </ul>
178 <ol>
179   <li>new list</li>
180 </ol>
181 SLAB
182
183 # 1415 characters, 2061 bytes
184 longer_slab_of_UTF8_text  = <<SLAB
185 pärägräph
186 ∫€cöñd lîñ€
187
188 ñ€w pärägräph
189
190 = ä h€ädîñg =
191
192 > ä blöckquöt€
193 > ∫€cöñd lîñ€ öf blöckquöt€
194 >
195 > ñ€w pärägräph wîthîñ blöckquöt€
196
197 == äñöth€r h€ädîñg ==
198
199 pärägräph wîthîñ ''multîpl€ '''∫tyl€∫''''' äñd <tt>tt ∫päñ</tt>
200
201 ∫îmîlär, but wîth '''∫tyl€∫ îñ ''dîff€r€ñt'' örd€r'''
202
203 ägäîñ, ä '''dîff€r€ñt ''örd€r'''''
204
205 * lî∫t ît€m 1
206 ** ñ€∫t€d lî∫t ît€m 1
207 ** ñ€∫t€d lî∫t ît€m 2
208 ** ñ€∫t€d lî∫t ît€m 3
209 * lî∫t ît€m 2
210
211  // thî∫ î∫ ä cöd€ blöck
212  ñötîc€ höw ît cäñ cöñtäîñ ''märkup''
213  whîch wöuld '''öth€rwî∫€''' häv€ <tt>∫p€cîäl</tt> m€äñîñg
214  älthöugh €xplîcît €ñtîtî€∫ &cöpy; är€ pä∫∫€d thröugh uñchäñg€d
215
216 ä ñörmäl pärägräph ägäîñ
217
218 Thî∫ î∫ wh€r€ w€ ∫höw ä lîñk tö äñ ärtîcl€ öñ [[GCC]].
219 R€lät€d tö thät, [[GCC|ä lîñk]] tö th€ ∫äm€
220 ärtîcl€ but wîth cu∫töm lîñk t€xt.
221
222 Ext€rñäl lîñk∫ [http://example.com wörk töö].
223 A∫ w€ll ä∫ äutölîñk∫ ä∫ ∫€€ñ http://example.com/
224 her€.
225
226 Löök ät höw w€ häñdl€ bäd ∫yñtäx. [[Thî∫ î∫ äñ uñt€rmîñät€d
227 lîñk. Añd [http://example.com/ î∫ äñöth€r.
228
229 # thî∫ î∫ äñ örd€r€d lî∫t
230 # whîch cöñtîñu€∫
231 ## äñd hä∫ äñöth€r örd€r€d lî∫t
232 ## ñ€∫t€d îñ∫îd€ ît
233 # äñd th€ñ fäll∫ bäck
234 #* äñd th€ñ ñ€∫t∫ äñöth€r lî∫t
235 #* thî∫ tîm€ äñ uñörd€r€d öñ€
236 #** ît∫€lf cöñtäîñîñg ä ñ€∫t€d lî∫t
237 #** whîch cöñtîñu€∫
238 #**# äñd fîñälly ñ€∫t∫ y€t äñöth€r örd€r€d lî∫t
239 #**# whîch cöñtîñu€∫
240 #* dröp∫ bäck quît€ ä wäy
241 # äñd fîñälly äll th€ wäy
242 #****** äñd fîñî∫h€∫ wîth äñ îñvälîd ît€m
243
244 === h€ädîñg wîth mî∫∫îñg clö∫îñg täg
245 * lî∫t
246 # ñ€w lî∫t
247 SLAB
248
249 longer_slab_of_UTF8_text_output = <<SLAB
250 <p>p&#x00e4;r&#x00e4;gr&#x00e4;ph &#x222b;&#x20ac;c&#x00f6;&#x00f1;d l&#x00ee;&#x00f1;&#x20ac;</p>
251 <p>&#x00f1;&#x20ac;w p&#x00e4;r&#x00e4;gr&#x00e4;ph</p>
252 <h1>&#x00e4; h&#x20ac;&#x00e4;d&#x00ee;&#x00f1;g</h1>
253 <blockquote>
254   <p>&#x00e4; bl&#x00f6;ckqu&#x00f6;t&#x20ac; &#x222b;&#x20ac;c&#x00f6;&#x00f1;d l&#x00ee;&#x00f1;&#x20ac; &#x00f6;f bl&#x00f6;ckqu&#x00f6;t&#x20ac;</p>
255   <p>&#x00f1;&#x20ac;w p&#x00e4;r&#x00e4;gr&#x00e4;ph w&#x00ee;th&#x00ee;&#x00f1; bl&#x00f6;ckqu&#x00f6;t&#x20ac;</p>
256 </blockquote>
257 <h2>&#x00e4;&#x00f1;&#x00f6;th&#x20ac;r h&#x20ac;&#x00e4;d&#x00ee;&#x00f1;g</h2>
258 <p>p&#x00e4;r&#x00e4;gr&#x00e4;ph w&#x00ee;th&#x00ee;&#x00f1; <em>mult&#x00ee;pl&#x20ac; <strong>&#x222b;tyl&#x20ac;&#x222b;</strong></em> &#x00e4;&#x00f1;d <tt>tt &#x222b;p&#x00e4;&#x00f1;</tt></p>
259 <p>&#x222b;&#x00ee;m&#x00ee;l&#x00e4;r, but w&#x00ee;th <strong>&#x222b;tyl&#x20ac;&#x222b; &#x00ee;&#x00f1; <em>d&#x00ee;ff&#x20ac;r&#x20ac;&#x00f1;t</em> &#x00f6;rd&#x20ac;r</strong></p>
260 <p>&#x00e4;g&#x00e4;&#x00ee;&#x00f1;, &#x00e4; <strong>d&#x00ee;ff&#x20ac;r&#x20ac;&#x00f1;t <em>&#x00f6;rd&#x20ac;r</em></strong></p>
261 <ul>
262   <li>l&#x00ee;&#x222b;t &#x00ee;t&#x20ac;m 1
263     <ul>
264       <li>&#x00f1;&#x20ac;&#x222b;t&#x20ac;d l&#x00ee;&#x222b;t &#x00ee;t&#x20ac;m 1</li>
265       <li>&#x00f1;&#x20ac;&#x222b;t&#x20ac;d l&#x00ee;&#x222b;t &#x00ee;t&#x20ac;m 2</li>
266       <li>&#x00f1;&#x20ac;&#x222b;t&#x20ac;d l&#x00ee;&#x222b;t &#x00ee;t&#x20ac;m 3</li>
267     </ul>
268   </li>
269   <li>l&#x00ee;&#x222b;t &#x00ee;t&#x20ac;m 2</li>
270 </ul>
271 <pre>// th&#x00ee;&#x222b; &#x00ee;&#x222b; &#x00e4; c&#x00f6;d&#x20ac; bl&#x00f6;ck
272 &#x00f1;&#x00f6;t&#x00ee;c&#x20ac; h&#x00f6;w &#x00ee;t c&#x00e4;&#x00f1; c&#x00f6;&#x00f1;t&#x00e4;&#x00ee;&#x00f1; ''m&#x00e4;rkup''
273 wh&#x00ee;ch w&#x00f6;uld '''&#x00f6;th&#x20ac;rw&#x00ee;&#x222b;&#x20ac;''' h&#x00e4;v&#x20ac; &lt;tt&gt;&#x222b;p&#x20ac;c&#x00ee;&#x00e4;l&lt;/tt&gt; m&#x20ac;&#x00e4;&#x00f1;&#x00ee;&#x00f1;g
274 &#x00e4;lth&#x00f6;ugh &#x20ac;xpl&#x00ee;c&#x00ee;t &#x20ac;&#x00f1;t&#x00ee;t&#x00ee;&#x20ac;&#x222b; &amp;c&#x00f6;py; &#x00e4;r&#x20ac; p&#x00e4;&#x222b;&#x222b;&#x20ac;d thr&#x00f6;ugh u&#x00f1;ch&#x00e4;&#x00f1;g&#x20ac;d</pre>
275 <p>&#x00e4; &#x00f1;&#x00f6;rm&#x00e4;l p&#x00e4;r&#x00e4;gr&#x00e4;ph &#x00e4;g&#x00e4;&#x00ee;&#x00f1;</p>
276 <p>Th&#x00ee;&#x222b; &#x00ee;&#x222b; wh&#x20ac;r&#x20ac; w&#x20ac; &#x222b;h&#x00f6;w &#x00e4; l&#x00ee;&#x00f1;k t&#x00f6; &#x00e4;&#x00f1; &#x00e4;rt&#x00ee;cl&#x20ac; &#x00f6;&#x00f1; <a href="/wiki/GCC">GCC</a>. R&#x20ac;l&#x00e4;t&#x20ac;d t&#x00f6; th&#x00e4;t, <a href="/wiki/GCC">&#x00e4; l&#x00ee;&#x00f1;k</a> t&#x00f6; th&#x20ac; &#x222b;&#x00e4;m&#x20ac; &#x00e4;rt&#x00ee;cl&#x20ac; but w&#x00ee;th cu&#x222b;t&#x00f6;m l&#x00ee;&#x00f1;k t&#x20ac;xt.</p>
277 <p>Ext&#x20ac;r&#x00f1;&#x00e4;l l&#x00ee;&#x00f1;k&#x222b; <a href="http://example.com" class="external">w&#x00f6;rk t&#x00f6;&#x00f6;</a>. A&#x222b; w&#x20ac;ll &#x00e4;&#x222b; &#x00e4;ut&#x00f6;l&#x00ee;&#x00f1;k&#x222b; &#x00e4;&#x222b; &#x222b;&#x20ac;&#x20ac;&#x00f1; <a href="http://example.com/" class="external">http://example.com/</a> her&#x20ac;.</p>
278 <p>L&#x00f6;&#x00f6;k &#x00e4;t h&#x00f6;w w&#x20ac; h&#x00e4;&#x00f1;dl&#x20ac; b&#x00e4;d &#x222b;y&#x00f1;t&#x00e4;x. [[Th&#x00ee;&#x222b; &#x00ee;&#x222b; &#x00e4;&#x00f1; u&#x00f1;t&#x20ac;rm&#x00ee;&#x00f1;&#x00e4;t&#x20ac;d l&#x00ee;&#x00f1;k. A&#x00f1;d [<a href="http://example.com/" class="external">http://example.com/</a> &#x00ee;&#x222b; &#x00e4;&#x00f1;&#x00f6;th&#x20ac;r.</p>
279 <ol>
280   <li>th&#x00ee;&#x222b; &#x00ee;&#x222b; &#x00e4;&#x00f1; &#x00f6;rd&#x20ac;r&#x20ac;d l&#x00ee;&#x222b;t</li>
281   <li>wh&#x00ee;ch c&#x00f6;&#x00f1;t&#x00ee;&#x00f1;u&#x20ac;&#x222b;
282     <ol>
283       <li>&#x00e4;&#x00f1;d h&#x00e4;&#x222b; &#x00e4;&#x00f1;&#x00f6;th&#x20ac;r &#x00f6;rd&#x20ac;r&#x20ac;d l&#x00ee;&#x222b;t</li>
284       <li>&#x00f1;&#x20ac;&#x222b;t&#x20ac;d &#x00ee;&#x00f1;&#x222b;&#x00ee;d&#x20ac; &#x00ee;t</li>
285     </ol>
286   </li>
287   <li>&#x00e4;&#x00f1;d th&#x20ac;&#x00f1; f&#x00e4;ll&#x222b; b&#x00e4;ck
288     <ul>
289       <li>&#x00e4;&#x00f1;d th&#x20ac;&#x00f1; &#x00f1;&#x20ac;&#x222b;t&#x222b; &#x00e4;&#x00f1;&#x00f6;th&#x20ac;r l&#x00ee;&#x222b;t</li>
290       <li>th&#x00ee;&#x222b; t&#x00ee;m&#x20ac; &#x00e4;&#x00f1; u&#x00f1;&#x00f6;rd&#x20ac;r&#x20ac;d &#x00f6;&#x00f1;&#x20ac;
291         <ul>
292           <li>&#x00ee;t&#x222b;&#x20ac;lf c&#x00f6;&#x00f1;t&#x00e4;&#x00ee;&#x00f1;&#x00ee;&#x00f1;g &#x00e4; &#x00f1;&#x20ac;&#x222b;t&#x20ac;d l&#x00ee;&#x222b;t</li>
293           <li>wh&#x00ee;ch c&#x00f6;&#x00f1;t&#x00ee;&#x00f1;u&#x20ac;&#x222b;
294             <ol>
295               <li>&#x00e4;&#x00f1;d f&#x00ee;&#x00f1;&#x00e4;lly &#x00f1;&#x20ac;&#x222b;t&#x222b; y&#x20ac;t &#x00e4;&#x00f1;&#x00f6;th&#x20ac;r &#x00f6;rd&#x20ac;r&#x20ac;d l&#x00ee;&#x222b;t</li>
296               <li>wh&#x00ee;ch c&#x00f6;&#x00f1;t&#x00ee;&#x00f1;u&#x20ac;&#x222b;</li>
297             </ol>
298           </li>
299         </ul>
300       </li>
301       <li>dr&#x00f6;p&#x222b; b&#x00e4;ck qu&#x00ee;t&#x20ac; &#x00e4; w&#x00e4;y</li>
302     </ul>
303   </li>
304   <li>&#x00e4;&#x00f1;d f&#x00ee;&#x00f1;&#x00e4;lly &#x00e4;ll th&#x20ac; w&#x00e4;y
305     <ul>
306       <li>***** &#x00e4;&#x00f1;d f&#x00ee;&#x00f1;&#x00ee;&#x222b;h&#x20ac;&#x222b; w&#x00ee;th &#x00e4;&#x00f1; &#x00ee;&#x00f1;v&#x00e4;l&#x00ee;d &#x00ee;t&#x20ac;m</li>
307     </ul>
308   </li>
309 </ol>
310 <h3>h&#x20ac;&#x00e4;d&#x00ee;&#x00f1;g w&#x00ee;th m&#x00ee;&#x222b;&#x222b;&#x00ee;&#x00f1;g cl&#x00f6;&#x222b;&#x00ee;&#x00f1;g t&#x00e4;g</h3>
311 <ul>
312   <li>l&#x00ee;&#x222b;t</li>
313 </ul>
314 <ol>
315   <li>&#x00f1;&#x20ac;w l&#x00ee;&#x222b;t</li>
316 </ol>
317 SLAB
318
319 def parse job, description, parser, input
320   job.report(description) do
321     parser.profiling_parse input
322   end
323 end
324
325 parser = Wikitext::Parser.new
326
327 # sanity check
328 raise 'mismatch (short slab of ASCII text)' unless (parser.parse(short_slab_of_ASCII_text) == short_slab_of_ASCII_text_output)
329 raise 'mismatch (short slab of UTF-8 text)' unless (parser.parse(short_slab_of_UTF8_text) == short_slab_of_UTF8_text_output)
330 raise 'mismatch (longer slab of ASCII text)' unless (parser.parse(longer_slab_of_ASCII_text) == longer_slab_of_ASCII_text_output)
331 raise 'mismatch (longer slab of UTF-8 text)' unless (parser.parse(longer_slab_of_UTF8_text) == longer_slab_of_UTF8_text_output)
332
333 Benchmark.bmbm do |job|
334   parse job, 'short slab of ASCII text', parser, short_slab_of_ASCII_text
335   parse job, 'short slab of UTF-8 text', parser, short_slab_of_UTF8_text
336   parse job, 'longer slab of ASCII text', parser, longer_slab_of_ASCII_text
337   parse job, 'longer slab of UTF-8 text', parser, longer_slab_of_UTF8_text
338 end