packages feed

aeson 0.4.0.0 → 0.4.0.1

raw patch · 7 files changed

+147/−31 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Data/Aeson/Encode.hs view
@@ -17,13 +17,15 @@     , encode     ) where -import Blaze.ByteString.Builder-import Blaze.ByteString.Builder.Char.Utf8-import Data.Attoparsec.Number (Number(..))+import Blaze.ByteString.Builder (Builder, fromByteString, toLazyByteString)+import Blaze.Text (double, integral) import Data.Aeson.Types (ToJSON(..), Value(..))+import Data.Attoparsec.Number (Number(..)) import Data.Monoid (mappend)+import Data.Text.Encoding (encodeUtf8) import Numeric (showHex)-import Blaze.Text (double, integral)+import qualified Blaze.ByteString.Builder.Char.Utf8 as Utf8+import qualified Blaze.ByteString.Builder.Char8 as Char8 import qualified Data.ByteString.Lazy.Char8 as L import qualified Data.HashMap.Strict as H import qualified Data.Text as T@@ -31,27 +33,29 @@  -- | Encode a JSON value to a 'Builder'. fromValue :: Value -> Builder-fromValue Null = fromByteString "null"-fromValue (Bool b) = fromByteString $ if b then "true" else "false"-fromValue (Number n) = fromNumber n-fromValue (String s) = string s+fromValue Null = {-# SCC "fromValue/Null" #-} fromByteString "null"+fromValue (Bool b) = {-# SCC "fromValue/Bool" #-}+                     if b then fromByteString "true"+                     else fromByteString "false"+fromValue (Number n) = {-# SCC "fromValue/Number" #-} fromNumber n+fromValue (String s) = {-# SCC "fromValue/String" #-} string s fromValue (Array v)-    | V.null v = fromByteString "[]"-    | otherwise = fromChar '[' `mappend`+    | V.null v = {-# SCC "fromValue/Array" #-} fromByteString "[]"+    | otherwise = {-# SCC "fromValue/Array" #-}+                  Char8.fromChar '[' `mappend`                   fromValue (V.unsafeHead v) `mappend`-                  V.foldr f (fromChar ']') (V.unsafeTail v)-  where f a z = fromChar ',' `mappend` fromValue a `mappend` z-fromValue (Object m) =+                  V.foldr f (Char8.fromChar ']') (V.unsafeTail v)+  where f a z = Char8.fromChar ',' `mappend` fromValue a `mappend` z+fromValue (Object m) = {-# SCC "fromValue/Object" #-}     case H.toList m of-      (x:xs) -> fromChar '{' `mappend`-                one x `mappend`-                foldr f (fromChar '}') xs-      _ -> fromByteString "{}"-  where f a z     = fromChar ',' `mappend` one a `mappend` z-        one (k,v) = string k `mappend` fromChar ':' `mappend` fromValue v+      (x:xs) -> Char8.fromChar '{' `mappend`+                one x `mappend` foldr f (Char8.fromChar '}') xs+      _      -> fromByteString "{}"+  where f a z     = Char8.fromChar ',' `mappend` one a `mappend` z+        one (k,v) = string k `mappend` Char8.fromChar ':' `mappend` fromValue v  string :: T.Text -> Builder-string s = fromChar '"' `mappend` quote s `mappend` fromChar '"'+string s = Char8.fromChar '"' `mappend` (quote s) `mappend` Char8.fromChar '"'   where     quote q = case T.uncons t of                 Just (c,t') -> fromText h `mappend` escape c `mappend` quote t'@@ -64,10 +68,15 @@     escape '\r' = fromByteString "\\r"     escape '\t' = fromByteString "\\t"     escape c-        | c < '\x20' = fromString $ "\\u" ++ replicate (4 - length h) '0' ++ h-        | otherwise  = fromChar c+        | c < '\x20' = Char8.fromString $+                       "\\u" ++ replicate (4 - length h) '0' ++ h+        | otherwise  = Utf8.fromChar c         where h = showHex (fromEnum c) "" +-- The version in blaze-builder is way slower.+fromText :: T.Text -> Builder+fromText t = fromByteString (encodeUtf8 t)+ fromNumber :: Number -> Builder fromNumber (I i) = integral i fromNumber (D d)@@ -76,5 +85,6 @@  -- | Efficiently serialize a JSON value as a lazy 'L.ByteString'. encode :: ToJSON a => a -> L.ByteString-encode = toLazyByteString . fromValue . toJSON+encode = {-# SCC "encode" #-} toLazyByteString . fromValue .+         {-# SCC "toJSON" #-} toJSON {-# INLINE encode #-}
aeson.cabal view
@@ -1,5 +1,5 @@ name:            aeson-version:         0.4.0.0+version:         0.4.0.1 license:         BSD3 license-file:    LICENSE category:        Text, Web, JSON@@ -84,6 +84,7 @@  extra-source-files:     README.markdown+    benchmarks/*.cabal     benchmarks/*.hs     benchmarks/*.py     benchmarks/Makefile@@ -139,7 +140,7 @@     ghc-options: -Werror     ghc-prof-options: -auto-all -  ghc-options:      -Wall+  ghc-options: -O2 -Wall  test-suite tests   type:           exitcode-stdio-1.0
benchmarks/AesonEncode.hs view
@@ -3,8 +3,6 @@ import Control.Exception import Control.Monad import Data.Aeson-import Data.Aeson.Encode-import Data.Aeson.Parser import Data.Attoparsec import Data.Time.Clock import System.Environment (getArgs)
benchmarks/AesonParse.hs view
@@ -1,10 +1,8 @@ {-# LANGUAGE BangPatterns, OverloadedStrings #-} -import Control.DeepSeq import Control.Exception import Control.Monad import Data.Aeson-import Data.Aeson.Parser import Data.Attoparsec import Data.Time.Clock import System.Environment (getArgs)
+ benchmarks/CompareWithJSON.hs view
@@ -0,0 +1,70 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++import Blaze.ByteString.Builder (toLazyByteString)+import Blaze.ByteString.Builder.Char.Utf8 (fromString)+import Control.DeepSeq (NFData(rnf))+import Criterion.Main+import qualified Data.Aeson as A+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString.Lazy.Internal as BL+import qualified Text.JSON as J++instance (NFData v) => NFData (J.JSObject v) where+  rnf o = rnf (J.fromJSObject o)++instance NFData J.JSValue where+  rnf J.JSNull = ()+  rnf (J.JSBool b) = rnf b+  rnf (J.JSRational a b) = rnf a `seq` rnf b `seq` ()+  rnf (J.JSString s) = rnf (J.fromJSString s)+  rnf (J.JSArray lst) = rnf lst+  rnf (J.JSObject o) = rnf o++instance NFData BL.ByteString where+  rnf (BL.Chunk _ bs) = rnf bs+  rnf BL.Empty        = ()++decodeJ :: String -> J.JSValue+decodeJ s =+  case J.decodeStrict s of+    J.Ok v -> v+    J.Error _ -> error "fail to parse via JSON"++decodeA :: BL.ByteString -> A.Value+decodeA s = case A.decode s of+              Just v -> v+              Nothing -> error "fail to parse via Aeson"++encodeJ :: J.JSValue -> BL.ByteString+encodeJ = toLazyByteString . fromString . J.encode++main :: IO ()+main = do+  let enFile = "json-data/twitter100.json"+      jpFile = "json-data/jp100.json"+  enA <- BL.readFile enFile+  enJ <- readFile enFile+  jpA <- BL.readFile jpFile+  jpJ <- readFile jpFile+  defaultMain [+      bgroup "decode" [+        bgroup "en" [+          bench "aeson" $ nf decodeA enA+        , bench "json"  $ nf decodeJ enJ+        ]+      , bgroup "jp" [+          bench "aeson" $ nf decodeA jpA+        , bench "json"  $ nf decodeJ jpJ+        ]+      ]+    , bgroup "encode" [+        bgroup "en" [+          bench "aeson" $ nf A.encode (decodeA enA)+        , bench "json"  $ nf encodeJ (decodeJ enJ)+        ]+      , bgroup "jp" [+          bench "aeson" $ nf A.encode (decodeA jpA)+        , bench "json"  $ nf encodeJ (decodeJ jpJ)+        ]+      ]+    ]
benchmarks/JsonParse.hs view
@@ -1,13 +1,12 @@ {-# LANGUAGE BangPatterns, ScopedTypeVariables #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}  import Control.DeepSeq-import Control.Exception import Control.Monad import Text.JSON import Data.Time.Clock import System.Environment (getArgs) import System.IO-import qualified Data.ByteString as B  instance NFData JSValue where     rnf JSNull = ()
+ benchmarks/aeson-benchmarks.cabal view
@@ -0,0 +1,40 @@+name:                aeson-benchmarks+version:             0+build-type:          Simple++cabal-version:       >=1.2++executable aeson-benchmark-compare-with-json+  main-is: CompareWithJSON.hs+  ghc-options: -Wall -O2+  build-depends:+    aeson == 0.4.0.0,+    base,+    blaze-builder,+    bytestring,+    criterion,+    json++executable aeson-benchmark-aeson-encode+  main-is: AesonEncode.hs+  ghc-options: -Wall -O2+  build-depends:+    aeson == 0.4.0.0,+    base++executable aeson-benchmark-aeson-parse+  main-is: AesonParse.hs+  ghc-options: -Wall -O2+  build-depends:+    aeson == 0.4.0.0,+    attoparsec,+    base++executable aeson-benchmark-json-parse+  main-is: JsonParse.hs+  ghc-options: -Wall -O2+  build-depends:+    base,+    deepseq,+    json,+    time