packages feed

json-stream 0.4.2.1 → 0.4.2.2

raw patch · 3 files changed

+39/−19 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Data/JsonStream/Parser.hs view
@@ -232,14 +232,13 @@       process _ _ _ = Failed "Unexpected error in parallel processing <|>"    some = filterI (not . null) . many-  many f = Parser $ \ntok -> loop [] (callParse f ntok)+  many f = Parser $ \ntok -> loop id (callParse f ntok)     where-      loop acc (Done ctx ntp) = Yield (reverse acc) (Done ctx ntp)+      loop acc (Done ctx ntp) = Yield (acc []) (Done ctx ntp)       loop acc (MoreData (Parser np, ntok)) = MoreData (Parser (loop acc . np), ntok)-      loop acc (Yield v np) = loop (v:acc) np+      loop acc (Yield v np) = loop (\nxt -> acc (v : nxt)) np       loop _ (Failed err) = Failed err - array' :: (Int -> Parser a) -> Parser a array' valparse = Parser $ \tp ->   case tp of@@ -375,8 +374,17 @@         JInteger val -> Yield (AE.Number $ fromIntegral val) (Done "" ntok)         StringContent _ -> callParse (AE.String <$> longString Nothing) tok         ArrayBegin -> AE.Array . Vec.fromList <$> callParse (many (arrayOf aeValue)) tok-        ObjectBegin -> AE.Object . HMap.fromList <$> callParse (many (objectItems aeValue)) tok+        ObjectBegin -> AE.Object . HMap.fromList <$> callParse (manyReverse (objectItems aeValue)) tok         _ -> Failed ("aeValue - unexpected token: " ++ show el)++-- | Optimized function for aeson objects - evades reversing the objects+manyReverse :: Parser a -> Parser [a]+manyReverse f = Parser $ \ntok -> loop [] (callParse f ntok)+  where+    loop acc (Done ctx ntp) = Yield acc (Done ctx ntp)+    loop acc (MoreData (Parser np, ntok)) = MoreData (Parser (loop acc . np), ntok)+    loop acc (Yield v np) = loop (v : acc) np+    loop _ (Failed err) = Failed err  -- | Convert a strict aeson value (no object/array) to a value. -- Non-matching type is ignored and not parsed (unlike 'value')
README.md view
@@ -2,11 +2,21 @@  [![Build Status](https://travis-ci.org/ondrap/json-stream.svg?branch=master)](https://travis-ci.org/ondrap/json-stream) [![Hackage](https://img.shields.io/hackage/v/json-stream.svg)](https://hackage.haskell.org/package/json-stream) +# When to use this library++- use [aeson](https://hackage.haskell.org/package/aeson) if you can; compile aeson with `cffi` flag if you need better performance+- use `json-stream` if you+  - need streaming+  - need every bit of performance (do profile; aeson is quite fast these days)+  - do not care that parsing may not fail on malformed JSON data+  - do not need advanced error reporting; json-stream tends to skip data that+    doesn't fit parsing rules (this might be implemented better in the future)++# Intro+ Most haskellers use the excellent [aeson](https://hackage.haskell.org/package/aeson) library to decode and encode JSON structures. Unfortunately, although very fast, this parser-must read the whole structure into memory. At a first sight it seemed that creating-an incremental JSON parser would be very hard thing to do; it turned out to be-remarkable easy. Just wondering, why nobody came with this earlier...+must read the whole structure into memory. Json-stream allows incremental parsing.  > Parsing performance is generally better than aeson, sometimes significantly better. > Json-stream uses a small and fast C lexer to parse the JSON into tokens. This results@@ -67,22 +77,24 @@ ``` ## Performance -Json-stream is fast. The crude lexing is done by a C-optimized code in batches, the-lexed pieces are then parsed using the user-specified parser. Compared to aeson, parsing-can be easily twice as fast, especially on larger structures.-Json-stream is in streaming mode much friendlier to the GC,-which makes the performance difference even bigger; however even when json-stream is used-as an aeson replacement (`value` parser), there can be a performance gain (running aeson benchmarks-has shown that json-stream is generally about twice as fast).+The crude lexing is done by a C-optimized code in batches, the+lexed pieces are then parsed using the user-specified parser. Json-stream+is generally slightly faster than aeson. It is significantly faster+in the following scenarios: +- parsing numbers+- parsing strings when aeson is not compiled with `cffi` flag+  (the `cffi` flag of aeson enables fast text decoding borrowed from json-stream)+- parsing only subset of big JSON structures++Json-stream is in streaming mode is also much friendlier to the GC.+ Using json-stream parser instead of aeson `value` evades the need to build the structure using aeson `Value` and then converting it to the user-requested structure. Instead the structure is built on the fly directly during the parsing phase.  Json-stream can optimize certain scenarios. If not all data from the input stream is-required, it is skipped by the parsers. Using `integer` parser-with bounded integer types (not `Integer`) avoids converting all numbers to-`Scientific` type.+required, it is skipped by the parsers.  ## Constant space parsing 
json-stream.cabal view
@@ -1,5 +1,5 @@ name:                json-stream-version:             0.4.2.1+version:             0.4.2.2 synopsis:            Incremental applicative JSON parser description:         Easy to use JSON parser fully supporting incremental parsing.                      Parsing grammar in applicative form.