7
7
-- |
8
8
-- | This benchmark suite also compares parsers to equivalent Regex. This
9
9
-- | provides an answer to the common question “How much slower is this package
10
- -- | than Regex?” Answer: approximately 100 ×. The Regex benchmarks also give
10
+ -- | than Regex?” Answer: approximately 10 ×. The Regex benchmarks also give
11
11
-- | us a rough way to calibrate benchmarks run on different platforms.
12
12
-- |
13
13
-- | `--expose-gc` is from
@@ -55,10 +55,11 @@ import Prelude
55
55
56
56
import Bench.Json.Parsing as BenchParsing
57
57
import Bench.Json.StringParser as BenchStringParser
58
- import Bench.Json.TestData (largeJson , mediumJson , smallJson )
59
- import Control.Monad.Trampoline (runTrampoline )
58
+ import Bench.Json.TestData (largeJson , mediumJson )
60
59
import Control.Monad.Free (liftF )
60
+ import Control.Monad.Trampoline (runTrampoline )
61
61
import Data.Array (fold , replicate )
62
+ import Data.Array as Array
62
63
import Data.Either (either )
63
64
import Data.List (many , manyRec )
64
65
import Data.List.Types (List )
@@ -69,37 +70,35 @@ import Effect (Effect)
69
70
import Effect.Console (log )
70
71
import Effect.Exception (throw )
71
72
import Effect.Unsafe (unsafePerformEffect )
72
- import Performance.Minibench (benchWith )
73
73
import Parsing (Parser , runParser , runParserT )
74
- import Parsing.String (string )
74
+ import Parsing.Combinators (chainl , chainlRec , chainr , chainrRec , manyTill , manyTillRec , manyTillRec_ , manyTill_ , sepBy , sepByRec )
75
+ import Parsing.String (anyChar , char , string )
75
76
import Parsing.String.Basic (digit )
77
+ import Performance.Minibench (benchWith )
76
78
import StringParser as StringParser
77
79
import StringParser.CodePoints as StringParser.CodePoints
78
80
import StringParser.CodeUnits as StringParser.CodeUnits
79
81
80
82
string23 :: String
81
83
string23 = " 23"
82
84
83
- string23_2 :: String
84
- string23_2 = fold $ replicate 2 string23
85
-
86
- -- string23_10000 :: String
87
- -- string23_10000 = fold $ replicate 10000 string23
85
+ string23_10000 :: String
86
+ string23_10000 = fold $ replicate 5000 string23
88
87
89
- string23_500 :: String
90
- string23_500 = fold $ replicate 500 string23
88
+ string23_10000x :: String
89
+ string23_10000x = string23_10000 <> " x "
91
90
92
- stringSkidoo :: String
93
- stringSkidoo = " skidoo "
91
+ string23_1000 :: String
92
+ string23_1000 = fold $ replicate 500 string23
94
93
95
- stringSkidoo_2 :: String
96
- stringSkidoo_2 = fold $ replicate 2 stringSkidoo
94
+ string23_1000x :: String
95
+ string23_1000x = string23_1000 <> " x "
97
96
98
- -- stringSkidoo_10000 :: String
99
- -- stringSkidoo_10000 = fold $ replicate 10000 stringSkidoo
97
+ stringSkidoo :: String
98
+ stringSkidoo = " skidoooooo "
100
99
101
- stringSkidoo_1000 :: String
102
- stringSkidoo_1000 = fold $ replicate 1000 stringSkidoo
100
+ stringSkidoo_100000 :: String
101
+ stringSkidoo_100000 = fold $ replicate 10000 stringSkidoo
103
102
104
103
parse23 :: Parser String (List Char )
105
104
parse23 = many digit
@@ -132,14 +131,14 @@ pattern23 = either (unsafePerformEffect <<< throw) identity
132
131
}
133
132
134
133
parseSkidoo :: Parser String (List String )
135
- parseSkidoo = many $ string " skidoo "
134
+ parseSkidoo = many $ string " skidoooooo "
136
135
137
136
parseSkidooRec :: Parser String (List String )
138
- parseSkidooRec = manyRec $ string " skidoo "
137
+ parseSkidooRec = manyRec $ string " skidoooooo "
139
138
140
139
patternSkidoo :: Regex
141
140
patternSkidoo = either (unsafePerformEffect <<< throw) identity
142
- $ regex " skidoo "
141
+ $ regex " skidoooooo "
143
142
$ RegexFlags
144
143
{ dotAll: true
145
144
, global: true
@@ -161,38 +160,109 @@ htmlTableWrap caption benchmark = do
161
160
main :: Effect Unit
162
161
main = do
163
162
log " <tr>"
164
- htmlTableWrap " runParser parse23" $ benchWith 200
165
- $ \_ -> runParser string23_500 parse23
166
- htmlTableWrap " StringParser.runParser parse23Points" $ benchWith 20
167
- $ \_ -> StringParser .runParser parse23Points string23_500
168
- htmlTableWrap " StringParser.runParser parse23Units" $ benchWith 200
169
- $ \_ -> StringParser .runParser parse23Units string23_500
170
- htmlTableWrap " runParser parse23Rec" $ benchWith 200
171
- $ \_ -> runParser string23_500 parse23Rec
172
- htmlTableWrap " StringParser.runParser parse23PointsRec" $ benchWith 20
173
- $ \_ -> StringParser .runParser parse23PointsRec string23_500
174
- htmlTableWrap " StringParser.runParser parse23UnitsRec" $ benchWith 200
175
- $ \_ -> StringParser .runParser parse23UnitsRec string23_500
176
- htmlTableWrap " Regex.match pattern23" $ benchWith 200
177
- $ \_ -> Regex .match pattern23 string23_500
178
- htmlTableWrap " runParser parseSkidoo" $ benchWith 200
179
- $ \_ -> runParser stringSkidoo_1000 parseSkidoo
180
- htmlTableWrap " runParser parseSkidooRec" $ benchWith 200
181
- $ \_ -> runParser stringSkidoo_1000 parseSkidooRec
182
- htmlTableWrap " Regex.match patternSkidoo" $ benchWith 200
183
- $ \_ -> Regex .match patternSkidoo stringSkidoo_1000
184
- htmlTableWrap " runParser json smallJson" $ benchWith 1000
185
- $ \_ -> runParser smallJson BenchParsing .json
186
- htmlTableWrap " runTrampoline runParser json smallJson" $ benchWith 1000
187
- $ \_ -> runTrampoline $ runParserT smallJson BenchParsing .json
188
- htmlTableWrap " StringParser.runParser json smallJson" $ benchWith 500
189
- $ \_ -> StringParser .runParser BenchStringParser .json smallJson
163
+
164
+ -- These inputs are too small for good measurement, but larger ones blow stack
165
+ -- log "<th><h2>digit 1000</h2></th>"
166
+ -- htmlTableWrap "runParser many digit 1000" $ benchWith 200
167
+ -- $ \_ -> runParser string23_1000 parse23
168
+ -- htmlTableWrap "StringParser many CodePoints.anyDigit 1000" $ benchWith 20
169
+ -- $ \_ -> StringParser.runParser parse23Points string23_1000
170
+ -- htmlTableWrap "StringParser many CodeUnits.anyDigit 1000" $ benchWith 200
171
+ -- $ \_ -> StringParser.runParser parse23Units string23_1000
172
+ -- htmlTableWrap "runParser manyRec digit 1000" $ benchWith 200
173
+ -- $ \_ -> runParser string23_1000 parse23Rec
174
+ -- htmlTableWrap "StringParser manyRec CodePoints.anyDigit 1000" $ benchWith 20
175
+ -- $ \_ -> StringParser.runParser parse23PointsRec string23_1000
176
+ -- htmlTableWrap "StringParser manyRec CodeUnits.anyDigit 1000" $ benchWith 200
177
+ -- $ \_ -> StringParser.runParser parse23UnitsRec string23_1000
178
+ -- htmlTableWrap "Regex.match \\d* 1000" $ benchWith 200
179
+ -- $ \_ -> Regex.match pattern23 string23_1000
180
+
181
+ log " <th><h2>digit 10000</h2></th>"
182
+ htmlTableWrap " runParser many digit 10000" $ benchWith 50
183
+ $ \_ -> runParser string23_10000 parse23
184
+ htmlTableWrap " runParser manyRec digit 10000" $ benchWith 50
185
+ $ \_ -> runParser string23_10000 parse23Rec
186
+ htmlTableWrap " runParser Array.many digit 10000" $ benchWith 50
187
+ $ \_ -> runParser string23_10000 (Array .many digit)
188
+ htmlTableWrap " StringParser manyRec CodePoints.anyDigit 10000" $ benchWith 20
189
+ $ \_ -> StringParser .runParser parse23PointsRec string23_10000
190
+ htmlTableWrap " StringParser manyRec CodeUnits.anyDigit 10000" $ benchWith 200
191
+ $ \_ -> StringParser .runParser parse23UnitsRec string23_10000
192
+ htmlTableWrap " Regex.match \\ d* 10000" $ benchWith 200
193
+ $ \_ -> Regex .match pattern23 string23_10000
194
+
195
+ log " <th><h2>string 100000</h2></th>"
196
+ htmlTableWrap " runParser many string" $ benchWith 200
197
+ $ \_ -> runParser stringSkidoo_100000 parseSkidoo
198
+ htmlTableWrap " runParser manyRec string" $ benchWith 200
199
+ $ \_ -> runParser stringSkidoo_100000 parseSkidooRec
200
+ htmlTableWrap " Regex.match literal*" $ benchWith 200
201
+ $ \_ -> Regex .match patternSkidoo stringSkidoo_100000
202
+
203
+ log " <th><h2>sepBy 1000</h2></th>"
204
+ htmlTableWrap " runParser sepBy 1000" $ benchWith 50
205
+ $ \_ -> runParser string23_1000 $ sepBy anyChar (char ' 3' )
206
+ htmlTableWrap " runParser sepByRec 1000" $ benchWith 50
207
+ $ \_ -> runParser string23_1000 $ sepByRec anyChar (char ' 3' )
208
+
209
+ log " <th><h2>sepBy 10000</h2></th>"
210
+ -- sepBy not stack-safe
211
+ -- htmlTableWrap "runParser sepBy 10000" $ benchWith 50
212
+ -- $ \_ -> runParser string23_10000 $ sepBy anyChar (char '3')
213
+ htmlTableWrap " runParser sepByRec 10000" $ benchWith 50
214
+ $ \_ -> runParser string23_10000 $ sepByRec anyChar (char ' 3' )
215
+
216
+ log " <th><h2>chainl 10000</h2></th>"
217
+ htmlTableWrap " runParser chainl 10000" $ benchWith 50
218
+ $ \_ -> runParser string23_10000 $ chainl anyChar (pure const) ' x'
219
+ htmlTableWrap " runParser chainlRec 10000" $ benchWith 50
220
+ $ \_ -> runParser string23_10000 $ chainlRec anyChar (pure const) ' x'
221
+
222
+ log " <th><h2>chainr 1000</h2></th>"
223
+ htmlTableWrap " runParser chainr 1000" $ benchWith 5
224
+ $ \_ -> runParser string23_1000 $ chainr anyChar (pure const) ' x'
225
+ htmlTableWrap " runParser chainrRec 1000" $ benchWith 5
226
+ $ \_ -> runParser string23_1000 $ chainrRec anyChar (pure const) ' x'
227
+
228
+ log " <th><h2>chainr 10000</h2></th>"
229
+ -- chainr not stack-safe
230
+ -- htmlTableWrap "runParser chainr 10000" $ benchWith 5
231
+ -- $ \_ -> runParser string23_10000 $ chainr anyChar (pure const) 'x'
232
+ htmlTableWrap " runParser chainrRec 10000" $ benchWith 5
233
+ $ \_ -> runParser string23_10000 $ chainrRec anyChar (pure const) ' x'
234
+
235
+ log " <th><h2>manyTill 1000</h2></th>"
236
+ htmlTableWrap " runParser manyTill 1000" $ benchWith 50
237
+ $ \_ -> runParser string23_1000x $ manyTill anyChar (char ' x' )
238
+ htmlTableWrap " runParser manyTillRec 1000" $ benchWith 50
239
+ $ \_ -> runParser string23_1000x $ manyTillRec anyChar (char ' x' )
240
+ htmlTableWrap " runParser manyTill_ 1000" $ benchWith 50
241
+ $ \_ -> runParser string23_1000x $ manyTill_ anyChar (char ' x' )
242
+ htmlTableWrap " runParser manyTillRec_ 1000" $ benchWith 50
243
+ $ \_ -> runParser string23_1000x $ manyTillRec_ anyChar (char ' x' )
244
+
245
+ log " <th><h2>manyTill 10000</h2></th>"
246
+ -- manyTill not stack-safe
247
+ -- htmlTableWrap "runParser manyTill 10000" $ benchWith 50
248
+ -- $ \_ -> runParser string23_10000x $ manyTill anyChar (char 'x')
249
+ htmlTableWrap " runParser manyTillRec 10000" $ benchWith 50
250
+ $ \_ -> runParser string23_10000x $ manyTillRec anyChar (char ' x' )
251
+ -- manyTill_ not stack-safe
252
+ -- htmlTableWrap "runParser manyTill_ 10000" $ benchWith 50
253
+ -- $ \_ -> runParser string23_10000x $ manyTill_ anyChar (char 'x')
254
+ htmlTableWrap " runParser manyTillRec_ 10000" $ benchWith 50
255
+ $ \_ -> runParser string23_10000x $ manyTillRec_ anyChar (char ' x' )
256
+
257
+ log " <th><h2>mediumJson</h2></th>"
190
258
htmlTableWrap " runParser json mediumJson" $ benchWith 500
191
259
$ \_ -> runParser mediumJson BenchParsing .json
192
260
htmlTableWrap " runTrampoline runParser json mediumJson" $ benchWith 500
193
261
$ \_ -> runTrampoline $ runParserT mediumJson BenchParsing .json
194
262
htmlTableWrap " StringParser.runParser json mediumJson" $ benchWith 1000
195
263
$ \_ -> StringParser .runParser BenchStringParser .json mediumJson
264
+
265
+ log " <th><h2>largeJson</h2></th>"
196
266
htmlTableWrap " runParser json largeJson" $ benchWith 100
197
267
$ \_ -> runParser largeJson BenchParsing .json
198
268
htmlTableWrap " runTrampoline runParser json largeJson" $ benchWith 100
0 commit comments