1{-# LANGUAGE BangPatterns, CPP #-}
3import Control.Applicative
4import Control.DeepSeq (NFData(rnf))
5import Criterion.Main (bench, bgroup, defaultMain, nf, whnf)
6import Data.Bits (unsafeShiftL)
7import Data.ByteString.Internal (ByteString(..))
9import Data.Scientific (Scientific(..))
10import Data.Word (Word32)
11import Text.Parsec.Text ()
12import Text.Parsec.Text.Lazy ()
13import qualified Data.Attoparsec.ByteString as AB
14import qualified Data.Attoparsec.ByteString.Char8 as AC
15import qualified Data.Attoparsec.ByteString.Lazy as ABL
16import qualified Data.Attoparsec.Text as AT
17import qualified Data.Attoparsec.Text.Lazy as ATL
18import qualified Data.ByteString as B
19import qualified Data.ByteString.Char8 as BC
20import qualified Data.ByteString.Lazy as BL
21import qualified Data.Text as T
22import qualified Data.Text.Lazy as TL
23import Data.Word (Word8)
24import qualified Text.Parsec as P
26#if !MIN_VERSION_bytestring(0,10,0)
27instance NFData ByteString where
31instance NFData P.ParseError where
34chunksOf :: Int -> [a] -> [[a]]
36 where go xs = case splitAt k xs of
40fromLazy :: BL.ByteString -> B.ByteString
41fromLazy = B.concat . BL.toChunks
44 let s = take 1024 . cycle $ ['a'..'z'] ++ ['A'..'Z']
46 !bl = BL.fromChunks . map BC.pack . chunksOf 4 $ s
48 !tl = TL.fromChunks . map T.pack . chunksOf 4 $ s
52 bench "B" $ nf (AB.parse (many (AC.satisfy AC.isAlpha_ascii))) b
53 , bench "BL" $ nf (ABL.parse (many (AC.satisfy AC.isAlpha_ascii))) bl
54 , bench "T" $ nf (AT.parse (many (AT.satisfy AC.isAlpha_ascii))) t
55 , bench "TL" $ nf (ATL.parse (many (AT.satisfy AC.isAlpha_ascii))) tl
58 bench "S" $ nf (P.parse (many (P.satisfy AC.isAlpha_ascii)) "") s
59 , bench "B" $ nf (P.parse (many (P.satisfy AC.isAlpha_ascii)) "") b
60 , bench "BL" $ nf (P.parse (many (P.satisfy AC.isAlpha_ascii)) "") bl
61 , bench "T" $ nf (P.parse (many (P.satisfy AC.isAlpha_ascii)) "") t
62 , bench "TL" $ nf (P.parse (many (P.satisfy AC.isAlpha_ascii)) "") tl
65 , bgroup "comparison" [
66 bgroup "many-vs-takeWhile" [
67 bench "many" $ nf (AB.parse (many (AC.satisfy AC.isAlpha_ascii))) b
68 , bench "takeWhile" $ nf (AB.parse (AC.takeWhile AC.isAlpha_ascii)) b
70 , bgroup "letter-vs-isAlpha" [
71 bench "letter" $ nf (AB.parse (many AC.letter_ascii)) b
72 , bench "isAlpha" $ nf (AB.parse (many (AC.satisfy AC.isAlpha_ascii))) b
75 , bgroup "takeWhile" [
76 bench "isAlpha" $ nf (ABL.parse (AC.takeWhile isAlpha)) bl
77 , bench "isAlpha_ascii" $ nf (ABL.parse (AC.takeWhile AC.isAlpha_ascii)) bl
78 , bench "isAlpha_iso8859_15" $ nf (ABL.parse (AC.takeWhile AC.isAlpha_iso8859_15)) bl
80 , bench "word32LE" $ nf (AB.parse word32LE) b
82 bench "short" $ nf (AB.parse quotedString) (BC.pack "abcdefghijk\"")
83 , bench "long" $ nf (AB.parse quotedString) b
86 , let strN = "1234.56789"
87 strNePos = "1234.56789e3"
88 strNeNeg = "1234.56789e-3"
91 [ let !tN = T.pack strN
92 !tNePos = T.pack strNePos
93 !tNeNeg = T.pack strNeNeg
97 [ bench "double" $ nf (AT.parseOnly AT.double) tN
98 , bench "number" $ nf (AT.parseOnly AT.number) tN
99 , bench "rational" $ nf (AT.parseOnly (AT.rational :: AT.Parser Rational)) tN
100 , bench "scientific" $ nf (AT.parseOnly (AT.rational :: AT.Parser Scientific)) tN
102 , bgroup "positive power"
103 [ bench "double" $ nf (AT.parseOnly AT.double) tNePos
104 , bench "number" $ nf (AT.parseOnly AT.number) tNePos
105 , bench "rational" $ nf (AT.parseOnly (AT.rational :: AT.Parser Rational)) tNePos
106 , bench "scientific" $ nf (AT.parseOnly (AT.rational :: AT.Parser Scientific)) tNePos
108 , bgroup "negative power"
109 [ bench "double" $ nf (AT.parseOnly AT.double) tNeNeg
110 , bench "number" $ nf (AT.parseOnly AT.number) tNeNeg
111 , bench "rational" $ nf (AT.parseOnly (AT.rational :: AT.Parser Rational)) tNeNeg
112 , bench "scientific" $ nf (AT.parseOnly (AT.rational :: AT.Parser Scientific)) tNeNeg
115 , let !bN = BC.pack strN
116 !bNePos = BC.pack strNePos
117 !bNeNeg = BC.pack strNeNeg
118 in bgroup "ByteString"
120 [ bench "double" $ nf (AC.parseOnly AC.double) bN
121 , bench "number" $ nf (AC.parseOnly AC.number) bN
122 , bench "rational" $ nf (AC.parseOnly (AC.rational :: AC.Parser Rational)) bN
123 , bench "scientific" $ nf (AC.parseOnly (AC.rational :: AC.Parser Scientific)) bN
125 , bgroup "positive power"
126 [ bench "double" $ nf (AC.parseOnly AC.double) bNePos
127 , bench "number" $ nf (AC.parseOnly AC.number) bNePos
128 , bench "rational" $ nf (AC.parseOnly (AC.rational :: AC.Parser Rational)) bNePos
129 , bench "scientific" $ nf (AC.parseOnly (AC.rational :: AC.Parser Scientific)) bNePos
131 , bgroup "negative power"
132 [ bench "double" $ nf (AC.parseOnly AC.double) bNeNeg
133 , bench "number" $ nf (AC.parseOnly AC.number) bNeNeg
134 , bench "rational" $ nf (AC.parseOnly (AC.rational :: AC.Parser Rational)) bNeNeg
135 , bench "scientific" $ nf (AC.parseOnly (AC.rational :: AC.Parser Scientific)) bNeNeg
141-- Benchmarks bind and (potential) bounds-check merging.
142word32LE :: AB.Parser Word32
148 return $! (fromIntegral w1 :: Word32) +
149 fromIntegral w2 `unsafeShiftL` 8 +
150 fromIntegral w3 `unsafeShiftL` 16 +
151 fromIntegral w4 `unsafeShiftL` 32
153doubleQuote, backslash :: Word8
156{-# INLINE backslash #-}
157{-# INLINE doubleQuote #-}
159-- | Parse a string without a leading quote.
160quotedString :: AB.Parser B.ByteString
161quotedString = AB.scan False $ \s c -> if s then Just False
162 else if c == doubleQuote
164 else Just (c == backslash)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list