1
+ {-# OPTIONS_GHC -fno-warn-orphans #-}
1
2
{-# LANGUAGE CPP #-}
2
3
{-# LANGUAGE LambdaCase #-}
4
+ {-# LANGUAGE DeriveGeneric #-}
3
5
{-# LANGUAGE TemplateHaskell #-}
4
6
{-# LANGUAGE TypeApplications #-}
5
7
6
8
module Main (main ) where
7
9
10
+ import Control.DeepSeq
8
11
import Criterion.Main
9
12
import Criterion.Types
10
13
import Data.Book
11
14
import Data.ByteString (ByteString )
12
15
import qualified Data.ByteString.Lazy
16
+ import qualified Data.Conduit
17
+ import qualified Data.Conduit.List
13
18
import Data.Default
14
19
import Data.FileEmbed
20
+ import GHC.Generics (Generic )
21
+ import qualified SAX
22
+ import qualified SAX.Streaming
23
+ import qualified Streaming.Prelude
15
24
import qualified Text.XML
16
25
import qualified Text.XML.DOM.Parser
26
+ import qualified Text.XML.Expat.SAX
17
27
import qualified Text.XML.Expat.Tree
18
28
import qualified Text.XML.Hexml
29
+ import qualified Text.XML.Stream.Parse
19
30
import qualified Xeno.DOM
31
+ import qualified Xeno.SAX
20
32
import qualified Xmlbf
21
33
import qualified Xmlbf.Xeno
22
34
#ifdef LIBXML
23
35
import qualified Text.XML.LibXML
24
36
#endif
25
37
38
+ data XenoEvent
39
+ = OpenTag ByteString
40
+ | EndOpenTag ByteString
41
+ | CloseTag ByteString
42
+ | Attribute ByteString ByteString
43
+ | Text ByteString
44
+ | CDATA ByteString
45
+ deriving (Generic )
46
+
47
+ instance NFData XenoEvent
48
+
26
49
main :: IO ()
27
50
main = defaultMainWith
28
51
defaultConfig { csvFile = Just " out.csv" }
29
- [ bgroup " dom" (dom inputBs)
30
- -- , bgroup "struct" (struct inputBs)
52
+ [ bgroup " sax" (sax inputBs)
53
+ , bgroup " dom" (dom inputBs)
54
+ , bgroup " struct" (struct inputBs)
31
55
]
32
56
33
- -- | Conversion from 'Data.ByteString.ByteString' to DOM
34
- dom :: Data.ByteString. ByteString -> [Benchmark ]
57
+ -- | Conversion from 'ByteString' to a list of SAX events
58
+ sax :: ByteString -> [Benchmark ]
59
+ sax bs =
60
+ [ bench " xeno fold list" $ nf
61
+ ( Xeno.SAX. fold
62
+ (\ v -> (: v) . OpenTag )
63
+ (\ v k -> (: v) . Attribute k)
64
+ (\ v -> (: v) . EndOpenTag )
65
+ (\ v -> (: v) . Text )
66
+ (\ v -> (: v) . CloseTag )
67
+ (\ v -> (: v) . CDATA )
68
+ mempty )
69
+ bs
70
+ , bench " xeno process conduit" $ nf
71
+ ( \ input ->
72
+ let
73
+ parseBs = Xeno.SAX. process
74
+ (Data.Conduit. yield . OpenTag )
75
+ (\ k -> Data.Conduit. yield . Attribute k)
76
+ (Data.Conduit. yield . EndOpenTag )
77
+ (Data.Conduit. yield . Text )
78
+ (Data.Conduit. yield . CloseTag )
79
+ (Data.Conduit. yield . CDATA )
80
+ input
81
+ in case Data.Conduit. connect parseBs Data.Conduit.List. consume of
82
+ Nothing -> error " Unexpected parse error"
83
+ Just v -> v )
84
+ bs
85
+ , bench " sax" $ nf
86
+ ( \ input -> case Streaming.Prelude. toList_ (SAX.Streaming. streamXml input) of
87
+ Left _ -> error " Unexpected parse error"
88
+ Right v -> v )
89
+ bs
90
+ , bench " hexpat" $ nf
91
+ ( Text.XML.Expat.SAX. parse @ ByteString @ ByteString Text.XML.Expat.SAX. defaultParseOptions )
92
+ ( Data.ByteString.Lazy. fromStrict bs )
93
+ , bench " conduit" $ nf
94
+ ( \ input -> case Data.Conduit. connect (Text.XML.Stream.Parse. parseLBS def input) Data.Conduit.List. consume of
95
+ Nothing -> error " Unexpected parse error"
96
+ Just v -> v )
97
+ ( Data.ByteString.Lazy. fromStrict bs )
98
+ ]
99
+
100
+ -- | Conversion from 'ByteString' to DOM
101
+ dom :: ByteString -> [Benchmark ]
35
102
dom bs =
36
103
[ bench " hexml" $ whnf
37
104
( \ input -> case Text.XML.Hexml. parse input of
@@ -59,13 +126,7 @@ dom bs =
59
126
-- | Conversion from DOM to data type
60
127
struct :: ByteString -> [Benchmark ]
61
128
struct bs =
62
- [ bench " dom-parser" $ nf
63
- ( \ doc -> case Text.XML.DOM.Parser. runDomParser doc (Text.XML.DOM.Parser. fromDom @ Catalog ) of
64
- Left _ -> error " Unexpected conversion error"
65
- Right v -> v )
66
- ( Text.XML. parseLBS_ def (Data.ByteString.Lazy. fromStrict bs) )
67
- -- TODO: https://gitlab.com/k0001/xmlbf/issues/6
68
- , bench " xmlbf-xeno" $ nf
129
+ [ bench " xmlbf-xeno" $ nf
69
130
( \ case
70
131
Left _ -> error " Unexpected parse error"
71
132
Right n -> case Xmlbf.Xeno. element n of
@@ -74,7 +135,22 @@ struct bs =
74
135
Left e -> error e
75
136
Right v -> v )
76
137
( Xeno.DOM. parse inputBs )
138
+ -- TODO: Fix @SAX.Fail "fail handler"@ error
139
+ -- , bench "sax" $ nf
140
+ -- ( \stream -> case SAX.parseSax rootSaxParser stream of
141
+ -- SAX.Partial _ _ _ -> error "Unexpected conversion error: Partial"
142
+ -- SAX.Done r -> r
143
+ -- SAX.Fail e -> error $ "Unexpected conversion error: Fail " ++ e )
144
+ -- ( SAX.Streaming.streamXml bs )
145
+ , bench " dom-parser" $ nf
146
+ ( \ doc -> case Text.XML.DOM.Parser. runDomParser doc (Text.XML.DOM.Parser. fromDom @ Catalog ) of
147
+ Left _ -> error " Unexpected conversion error"
148
+ Right v -> v )
149
+ ( Text.XML. parseLBS_ def (Data.ByteString.Lazy. fromStrict bs) )
77
150
]
78
151
79
152
inputBs :: ByteString
80
153
inputBs = $ (embedFile " in.xml" )
154
+
155
+ -- Assuming that SAX representation is strict (NF=WHNF)
156
+ instance NFData SAX.Streaming. SaxEvent where rnf = rwhnf
0 commit comments