Skip to content

Commit c695f6a

Browse files
authored
Merge pull request #176 from purescript-contrib/benchrec
Benchmark improvements
2 parents 17b247c + b80f958 commit c695f6a

File tree

2 files changed

+121
-51
lines changed

2 files changed

+121
-51
lines changed

bench/Main.purs

Lines changed: 119 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
-- |
88
-- | This benchmark suite also compares parsers to equivalent Regex. This
99
-- | 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
1111
-- | us a rough way to calibrate benchmarks run on different platforms.
1212
-- |
1313
-- | `--expose-gc` is from
@@ -55,10 +55,11 @@ import Prelude
5555

5656
import Bench.Json.Parsing as BenchParsing
5757
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)
6059
import Control.Monad.Free (liftF)
60+
import Control.Monad.Trampoline (runTrampoline)
6161
import Data.Array (fold, replicate)
62+
import Data.Array as Array
6263
import Data.Either (either)
6364
import Data.List (many, manyRec)
6465
import Data.List.Types (List)
@@ -69,37 +70,35 @@ import Effect (Effect)
6970
import Effect.Console (log)
7071
import Effect.Exception (throw)
7172
import Effect.Unsafe (unsafePerformEffect)
72-
import Performance.Minibench (benchWith)
7373
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)
7576
import Parsing.String.Basic (digit)
77+
import Performance.Minibench (benchWith)
7678
import StringParser as StringParser
7779
import StringParser.CodePoints as StringParser.CodePoints
7880
import StringParser.CodeUnits as StringParser.CodeUnits
7981

8082
string23 :: String
8183
string23 = "23"
8284

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
8887

89-
string23_500 :: String
90-
string23_500 = fold $ replicate 500 string23
88+
string23_10000x :: String
89+
string23_10000x = string23_10000 <> "x"
9190

92-
stringSkidoo :: String
93-
stringSkidoo = "skidoo"
91+
string23_1000 :: String
92+
string23_1000 = fold $ replicate 500 string23
9493

95-
stringSkidoo_2 :: String
96-
stringSkidoo_2 = fold $ replicate 2 stringSkidoo
94+
string23_1000x :: String
95+
string23_1000x = string23_1000 <> "x"
9796

98-
-- stringSkidoo_10000 :: String
99-
-- stringSkidoo_10000 = fold $ replicate 10000 stringSkidoo
97+
stringSkidoo :: String
98+
stringSkidoo = "skidoooooo"
10099

101-
stringSkidoo_1000 :: String
102-
stringSkidoo_1000 = fold $ replicate 1000 stringSkidoo
100+
stringSkidoo_100000 :: String
101+
stringSkidoo_100000 = fold $ replicate 10000 stringSkidoo
103102

104103
parse23 :: Parser String (List Char)
105104
parse23 = many digit
@@ -132,14 +131,14 @@ pattern23 = either (unsafePerformEffect <<< throw) identity
132131
}
133132

134133
parseSkidoo :: Parser String (List String)
135-
parseSkidoo = many $ string "skidoo"
134+
parseSkidoo = many $ string "skidoooooo"
136135

137136
parseSkidooRec :: Parser String (List String)
138-
parseSkidooRec = manyRec $ string "skidoo"
137+
parseSkidooRec = manyRec $ string "skidoooooo"
139138

140139
patternSkidoo :: Regex
141140
patternSkidoo = either (unsafePerformEffect <<< throw) identity
142-
$ regex "skidoo"
141+
$ regex "skidoooooo"
143142
$ RegexFlags
144143
{ dotAll: true
145144
, global: true
@@ -161,38 +160,109 @@ htmlTableWrap caption benchmark = do
161160
main :: Effect Unit
162161
main = do
163162
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>"
190258
htmlTableWrap "runParser json mediumJson" $ benchWith 500
191259
$ \_ -> runParser mediumJson BenchParsing.json
192260
htmlTableWrap "runTrampoline runParser json mediumJson" $ benchWith 500
193261
$ \_ -> runTrampoline $ runParserT mediumJson BenchParsing.json
194262
htmlTableWrap "StringParser.runParser json mediumJson" $ benchWith 1000
195263
$ \_ -> StringParser.runParser BenchStringParser.json mediumJson
264+
265+
log "<th><h2>largeJson</h2></th>"
196266
htmlTableWrap "runParser json largeJson" $ benchWith 100
197267
$ \_ -> runParser largeJson BenchParsing.json
198268
htmlTableWrap "runTrampoline runParser json largeJson" $ benchWith 100

bench/tabletranspose.xslt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ https://stackoverflow.com/questions/4410084/transpose-swap-x-y-axes-in-html-tabl
1010
<xsl:output omit-xml-declaration="yes"/>
1111
<xsl:template match="table">
1212
<table>
13-
<xsl:for-each select="tr[1]/td">
13+
<xsl:for-each select="tr[1]/*">
1414
<xsl:variable name="vRowPos" select="position()"/>
1515
<tr>
1616
<xsl:for-each select="/table/tr">
1717
<xsl:variable name="vColPos" select="position()"/>
18-
<xsl:copy-of select="/table/tr[$vColPos]/td[$vRowPos]"/>
18+
<xsl:copy-of select="/table/tr[$vColPos]/*[$vRowPos]"/>
1919
</xsl:for-each>
2020
</tr>
2121
</xsl:for-each>

0 commit comments

Comments
 (0)