git.iko.soy/typeable/attoparsec
on master help sign in
Merge from 0.11 branch
d7a77f6Bryan O'Sullivan
attoparsec.cabal+1
@@ -103,6 +103,7 @@ benchmark benchmarks
103 Common
103 Common
104 HeadersByteString
104 HeadersByteString
105 HeadersText
105 HeadersText
106+ Links
106 Numbers
107 Numbers
107 ghc-options: -O2 -Wall
108 ghc-options: -O2 -Wall
108
109
benchmarks/Benchmarks.hs+4−2
@@ -8,8 +8,6 @@ import Data.Word (Word32)
8import Data.Word (Word8)
8import Data.Word (Word8)
9import Numbers (numbers)
9import Numbers (numbers)
10import Common (chunksOf)
10import Common (chunksOf)
11−import qualified HeadersByteString
12−import qualified HeadersText
13import Text.Parsec.Text ()
11import Text.Parsec.Text ()
14import Text.Parsec.Text.Lazy ()
12import Text.Parsec.Text.Lazy ()
15import qualified Data.Attoparsec.ByteString as AB
13import qualified Data.Attoparsec.ByteString as AB
@@ -22,6 +20,9 @@ import qualified Data.ByteString.Char8 as BC
22import qualified Data.ByteString.Lazy as BL
20import qualified Data.ByteString.Lazy as BL
23import qualified Data.Text as T
21import qualified Data.Text as T
24import qualified Data.Text.Lazy as TL
22import qualified Data.Text.Lazy as TL
23+import qualified HeadersByteString
24+import qualified HeadersText
25+import qualified Links
25import qualified Text.Parsec as P
26import qualified Text.Parsec as P
26
27
27main :: IO ()
28main :: IO ()
@@ -72,6 +73,7 @@ main = do
72 ]
73 ]
73 , headersBS
74 , headersBS
74 , headersT
75 , headersT
76+ , Links.links
75 , numbers
77 , numbers
76 ]
78 ]
77
79
benchmarks/Links.hsnew file+63
@@ -0,0 +1,63 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Links (links) where
4+
5+import Control.Applicative
6+import Control.DeepSeq (NFData(..))
7+import Criterion.Main (Benchmark, bench, nf)
8+import Data.Attoparsec as A
9+import Data.Attoparsec.Char8 as A8
10+import Data.ByteString.Char8 as B8
11+
12+data Link = Link {
13+ linkURL :: ByteString
14+ , linkParams :: [(ByteString, ByteString)]
15+ } deriving (Eq, Show)
16+
17+instance NFData Link where
18+ rnf l = rnf (linkURL l) `seq` rnf (linkParams l)
19+
20+link :: Parser Link
21+link = Link <$> url <*> many (char8 ';' *> skipSpace *> param)
22+ where url = char8 '<' *> A8.takeTill (=='>') <* char8 '>' <* skipSpace
23+
24+param :: Parser (ByteString, ByteString)
25+param = do
26+ name <- paramName
27+ skipSpace *> "=" *> skipSpace
28+ c <- peekChar'
29+ let isTokenChar = A.inClass "!#$%&'()*+./0-9:<=>?@a-zA-Z[]^_`{|}~-"
30+ val <- case c of
31+ '"' -> quotedString
32+ _ -> A.takeWhile isTokenChar
33+ skipSpace
34+ return (name, val)
35+
36+data Quot = Literal | Backslash
37+
38+quotedString :: Parser ByteString
39+quotedString = char '"' *> (fixup <$> body) <* char '"'
40+ where body = A8.scan Literal $ \s c ->
41+ case (s,c) of
42+ (Literal, '\\') -> backslash
43+ (Literal, '"') -> Nothing
44+ _ -> literal
45+ literal = Just Literal
46+ backslash = Just Backslash
47+ fixup = B8.pack . go . B8.unpack
48+ where go ('\\' : x@'\\' : xs) = x : go xs
49+ go ('\\' : x@'"' : xs) = x : go xs
50+ go (x : xs) = x : go xs
51+ go xs = xs
52+
53+paramName :: Parser ByteString
54+paramName = do
55+ name <- A.takeWhile1 $ A.inClass "a-zA-Z0-9!#$&+-.^_`|~"
56+ c <- peekChar
57+ return $ case c of
58+ Just '*' -> B8.snoc name '*'
59+ _ -> name
60+
61+links :: Benchmark
62+links = bench "links" $ nf (A.parseOnly link) lnk
63+ where lnk = "<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=2>; rel=\"next\", <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel=\"last\""
benchmarks/attoparsec-benchmarks.cabal+1
@@ -12,6 +12,7 @@ executable attoparsec-benchmarks
12 Common
12 Common
13 HeadersByteString
13 HeadersByteString
14 HeadersText
14 HeadersText
15+ Links
15 Numbers
16 Numbers
16 hs-source-dirs: .. .
17 hs-source-dirs: .. .
17 ghc-options: -O2 -Wall
18 ghc-options: -O2 -Wall