on master help sign in
Switch to a peek-driven version of value

This drops use of the (<|>) combinator, and greatly reduces the extent to which we allocate unused thunks. As a result, it improves both runtime and heap usage significantly.

commitdcd86df36d3e4e9bdfeea2b71993fce6116cc2fd authorBryan O'Sullivan <bos@serpentine.com> dateTue 26 Nov 2013, 23:20 (13 years ago) parenta97ad0c
1 file changed+14−12
Data/Aeson/Parser/Internal.hs+14−12
Data/Aeson/Parser/Internal.hs+14−12
@@ -75,6 +75,8 @@ import qualified Data.HashMap.Strict as H
7575#define C_F 70
7676#define C_a 97
7777#define C_f 102
78+#define C_n 110
79+#define C_t 116
7880
7981-- | Parse a top-level JSON value. This must be either an object or
8082-- an array, per RFC 4627.
@@ -162,18 +164,18 @@ arrayValues val = do
162164-- implementations in other languages conform to that same restriction
163165-- to preserve interoperability and security.
164166value :: Parser Value
165−value = most <|> (Number <$> rational)
166− where
167− most = do
168− c <- satisfy (`B8.elem` "{[\"ftn")
169− case c of
170− '{' -> object_
171− '[' -> array_
172− '"' -> String <$> jstring_
173− 'f' -> string "alse" *> pure (Bool False)
174− 't' -> string "rue" *> pure (Bool True)
175− 'n' -> string "ull" *> pure Null
176− _ -> error "attoparsec panic! the impossible happened!"
167+value = do
168+ w <- A.peekWord8'
169+ case w of
170+ DOUBLE_QUOTE -> char '"' *> (String <$> jstring_)
171+ OPEN_CURLY -> char '{' *> object_
172+ OPEN_SQUARE -> char '[' *> array_
173+ C_f -> string "false" *> pure (Bool False)
174+ C_t -> string "true" *> pure (Bool True)
175+ C_n -> string "null" *> pure Null
176+ _ | w >= 48 && w <= 57 || w == 45
177+ -> Number <$> rational
178+ | otherwise -> fail "not a valid json value"
177179
178180-- | Strict version of 'value'. See also 'json''.
179181value' :: Parser Value