dhodovsk / source-git / ghc-aeson

Forked from source-git/ghc-aeson 4 years ago
Clone

Blame benchmarks/AesonCompareAutoInstances.hs

Packit 9a2dfb
{-# LANGUAGE DeriveGeneric #-}
Packit 9a2dfb
{-# LANGUAGE FlexibleContexts #-}
Packit 9a2dfb
{-# LANGUAGE TemplateHaskell #-}
Packit 9a2dfb
Packit 9a2dfb
module Main (main) where
Packit 9a2dfb
Packit 9a2dfb
import Prelude ()
Packit 9a2dfb
import Prelude.Compat
Packit 9a2dfb
Packit 9a2dfb
import Control.Monad
Packit 9a2dfb
import Control.DeepSeq (NFData, rnf, deepseq)
Packit 9a2dfb
import Criterion.Main hiding (defaultOptions)
Packit 9a2dfb
import Data.Aeson
Packit 9a2dfb
import Data.Aeson.Encoding
Packit 9a2dfb
import Data.Aeson.TH
Packit 9a2dfb
import Data.Aeson.Types
Packit 9a2dfb
import Data.ByteString.Lazy (ByteString)
Packit 9a2dfb
import Data.Data (Data)
Packit 9a2dfb
import Data.Typeable (Typeable)
Packit 9a2dfb
import GHC.Generics (Generic, Rep)
Packit 9a2dfb
import Options
Packit 9a2dfb
Packit 9a2dfb
toBS :: Encoding -> ByteString
Packit 9a2dfb
toBS = encodingToLazyByteString
Packit 9a2dfb
Packit 9a2dfb
gEncode :: (Generic a, GToEncoding Zero (Rep a)) => a -> ByteString
Packit 9a2dfb
gEncode = toBS . genericToEncoding opts
Packit 9a2dfb
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
Packit 9a2dfb
data D a = Nullary
Packit 9a2dfb
         | Unary Int
Packit 9a2dfb
         | Product String Char a
Packit 9a2dfb
         | Record { testOne   :: Double
Packit 9a2dfb
                  , testTwo   :: Bool
Packit 9a2dfb
                  , testThree :: D a
Packit 9a2dfb
                  }
Packit 9a2dfb
           deriving (Show, Eq)
Packit 9a2dfb
Packit 9a2dfb
deriveJSON opts ''D
Packit 9a2dfb
Packit 9a2dfb
instance NFData a => NFData (D a) where
Packit 9a2dfb
    rnf Nullary         = ()
Packit 9a2dfb
    rnf (Unary n)       = rnf n
Packit 9a2dfb
    rnf (Product s c x) = s `deepseq` c `deepseq` rnf x
Packit 9a2dfb
    rnf (Record d b y)  = d `deepseq` b `deepseq` rnf y
Packit 9a2dfb
Packit 9a2dfb
type T = D (D (D ()))
Packit 9a2dfb
Packit 9a2dfb
d :: T
Packit 9a2dfb
d = Record
Packit 9a2dfb
    { testOne = 1234.56789
Packit 9a2dfb
    , testTwo = True
Packit 9a2dfb
    , testThree = Product "Hello World!" 'a'
Packit 9a2dfb
                    Record
Packit 9a2dfb
                    { testOne   = 9876.54321
Packit 9a2dfb
                    , testTwo   = False
Packit 9a2dfb
                    , testThree = Product "Yeehaa!!!" '\n' Nullary
Packit 9a2dfb
                    }
Packit 9a2dfb
    }
Packit 9a2dfb
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
Packit 9a2dfb
data D' a = Nullary'
Packit 9a2dfb
          | Unary' Int
Packit 9a2dfb
          | Product' String Char a
Packit 9a2dfb
          | Record' { testOne'   :: Double
Packit 9a2dfb
                    , testTwo'   :: Bool
Packit 9a2dfb
                    , testThree' :: D' a
Packit 9a2dfb
                    }
Packit 9a2dfb
            deriving (Show, Eq, Generic)
Packit 9a2dfb
Packit 9a2dfb
instance ToJSON a => ToJSON (D' a) where
Packit 9a2dfb
    toJSON = genericToJSON opts
Packit 9a2dfb
Packit 9a2dfb
instance FromJSON a => FromJSON (D' a) where
Packit 9a2dfb
    parseJSON = genericParseJSON opts
Packit 9a2dfb
Packit 9a2dfb
instance NFData a => NFData (D' a) where
Packit 9a2dfb
    rnf Nullary'         = ()
Packit 9a2dfb
    rnf (Unary' n)       = rnf n
Packit 9a2dfb
    rnf (Product' s c x) = s `deepseq` c `deepseq` rnf x
Packit 9a2dfb
    rnf (Record' d b y)  = d `deepseq` b `deepseq` rnf y
Packit 9a2dfb
Packit 9a2dfb
type T' = D' (D' (D' ()))
Packit 9a2dfb
Packit 9a2dfb
d' :: T'
Packit 9a2dfb
d' = Record'
Packit 9a2dfb
    { testOne' = 1234.56789
Packit 9a2dfb
    , testTwo' = True
Packit 9a2dfb
    , testThree' = Product' "Hello World!" 'a'
Packit 9a2dfb
                    Record'
Packit 9a2dfb
                    { testOne'   = 9876.54321
Packit 9a2dfb
                    , testTwo'   = False
Packit 9a2dfb
                    , testThree' = Product' "Yeehaa!!!" '\n' Nullary'
Packit 9a2dfb
                    }
Packit 9a2dfb
    }
Packit 9a2dfb
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
Packit 9a2dfb
data BigRecord = BigRecord
Packit 9a2dfb
    { field01 :: !Int, field02 :: !Int, field03 :: !Int, field04 :: !Int, field05 :: !Int
Packit 9a2dfb
    , field06 :: !Int, field07 :: !Int, field08 :: !Int, field09 :: !Int, field10 :: !Int
Packit 9a2dfb
    , field11 :: !Int, field12 :: !Int, field13 :: !Int, field14 :: !Int, field15 :: !Int
Packit 9a2dfb
    , field16 :: !Int, field17 :: !Int, field18 :: !Int, field19 :: !Int, field20 :: !Int
Packit 9a2dfb
    , field21 :: !Int, field22 :: !Int, field23 :: !Int, field24 :: !Int, field25 :: !Int
Packit 9a2dfb
    } deriving (Show, Eq, Generic)
Packit 9a2dfb
Packit 9a2dfb
instance NFData BigRecord
Packit 9a2dfb
Packit 9a2dfb
bigRecord = BigRecord 1   2  3  4  5
Packit 9a2dfb
                      6   7  8  9 10
Packit 9a2dfb
                      11 12 13 14 15
Packit 9a2dfb
                      16 17 18 19 20
Packit 9a2dfb
                      21 22 23 24 25
Packit 9a2dfb
Packit 9a2dfb
return []
Packit 9a2dfb
Packit 9a2dfb
gBigRecordToJSON :: BigRecord -> Value
Packit 9a2dfb
gBigRecordToJSON = genericToJSON opts
Packit 9a2dfb
Packit 9a2dfb
gBigRecordEncode :: BigRecord -> ByteString
Packit 9a2dfb
gBigRecordEncode = gEncode
Packit 9a2dfb
Packit 9a2dfb
gBigRecordFromJSON :: Value -> Result BigRecord
Packit 9a2dfb
gBigRecordFromJSON = parse $ genericParseJSON opts
Packit 9a2dfb
Packit 9a2dfb
thBigRecordToJSON :: BigRecord -> Value
Packit 9a2dfb
thBigRecordToJSON = $(mkToJSON opts ''BigRecord)
Packit 9a2dfb
Packit 9a2dfb
thBigRecordEncode :: BigRecord -> ByteString
Packit 9a2dfb
thBigRecordEncode = toBS . $(mkToEncoding opts ''BigRecord)
Packit 9a2dfb
Packit 9a2dfb
thBigRecordFromJSON :: Value -> Result BigRecord
Packit 9a2dfb
thBigRecordFromJSON = parse $(mkParseJSON opts ''BigRecord)
Packit 9a2dfb
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
Packit 9a2dfb
data BigProduct = BigProduct
Packit 9a2dfb
    !Int !Int !Int !Int !Int
Packit 9a2dfb
    !Int !Int !Int !Int !Int
Packit 9a2dfb
    !Int !Int !Int !Int !Int
Packit 9a2dfb
    !Int !Int !Int !Int !Int
Packit 9a2dfb
    !Int !Int !Int !Int !Int
Packit 9a2dfb
    deriving (Show, Eq, Generic)
Packit 9a2dfb
Packit 9a2dfb
instance NFData BigProduct
Packit 9a2dfb
Packit 9a2dfb
bigProduct = BigProduct 1   2  3  4  5
Packit 9a2dfb
                        6   7  8  9 10
Packit 9a2dfb
                        11 12 13 14 15
Packit 9a2dfb
                        16 17 18 19 20
Packit 9a2dfb
                        21 22 23 24 25
Packit 9a2dfb
Packit 9a2dfb
return []
Packit 9a2dfb
Packit 9a2dfb
gBigProductToJSON :: BigProduct -> Value
Packit 9a2dfb
gBigProductToJSON = genericToJSON opts
Packit 9a2dfb
Packit 9a2dfb
gBigProductEncode :: BigProduct -> ByteString
Packit 9a2dfb
gBigProductEncode = gEncode
Packit 9a2dfb
Packit 9a2dfb
gBigProductFromJSON :: Value -> Result BigProduct
Packit 9a2dfb
gBigProductFromJSON = parse $ genericParseJSON opts
Packit 9a2dfb
Packit 9a2dfb
thBigProductToJSON :: BigProduct -> Value
Packit 9a2dfb
thBigProductToJSON = $(mkToJSON opts ''BigProduct)
Packit 9a2dfb
Packit 9a2dfb
thBigProductEncode :: BigProduct -> ByteString
Packit 9a2dfb
thBigProductEncode = toBS . $(mkToEncoding opts ''BigProduct)
Packit 9a2dfb
Packit 9a2dfb
thBigProductFromJSON :: Value -> Result BigProduct
Packit 9a2dfb
thBigProductFromJSON = parse $(mkParseJSON opts ''BigProduct)
Packit 9a2dfb
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
Packit 9a2dfb
data BigSum = F01 | F02 | F03 | F04 | F05
Packit 9a2dfb
            | F06 | F07 | F08 | F09 | F10
Packit 9a2dfb
            | F11 | F12 | F13 | F14 | F15
Packit 9a2dfb
            | F16 | F17 | F18 | F19 | F20
Packit 9a2dfb
            | F21 | F22 | F23 | F24 | F25
Packit 9a2dfb
    deriving (Show, Eq, Generic)
Packit 9a2dfb
Packit 9a2dfb
instance NFData BigSum
Packit 9a2dfb
Packit 9a2dfb
bigSum = F25
Packit 9a2dfb
Packit 9a2dfb
return []
Packit 9a2dfb
Packit 9a2dfb
gBigSumToJSON :: BigSum -> Value
Packit 9a2dfb
gBigSumToJSON = genericToJSON opts
Packit 9a2dfb
Packit 9a2dfb
gBigSumEncode :: BigSum -> ByteString
Packit 9a2dfb
gBigSumEncode = gEncode
Packit 9a2dfb
Packit 9a2dfb
gBigSumFromJSON :: Value -> Result BigSum
Packit 9a2dfb
gBigSumFromJSON = parse $ genericParseJSON opts
Packit 9a2dfb
Packit 9a2dfb
thBigSumToJSON :: BigSum -> Value
Packit 9a2dfb
thBigSumToJSON = $(mkToJSON opts ''BigSum)
Packit 9a2dfb
Packit 9a2dfb
thBigSumEncode :: BigSum -> ByteString
Packit 9a2dfb
thBigSumEncode = toBS . $(mkToEncoding opts ''BigSum)
Packit 9a2dfb
Packit 9a2dfb
thBigSumFromJSON :: Value -> Result BigSum
Packit 9a2dfb
thBigSumFromJSON = parse $(mkParseJSON opts ''BigSum)
Packit 9a2dfb
Packit 9a2dfb
--------------------------------------------------------------------------------
Packit 9a2dfb
Packit 9a2dfb
type FJ a = Value -> Result a
Packit 9a2dfb
Packit 9a2dfb
runBench :: IO ()
Packit 9a2dfb
runBench = defaultMain
Packit 9a2dfb
  [ let v = toJSON d
Packit 9a2dfb
    in (d, d', v) `deepseq`
Packit 9a2dfb
       bgroup "D"
Packit 9a2dfb
       [ group "toJSON"   (nf   toJSON d)
Packit 9a2dfb
                          (nf   toJSON d')
Packit 9a2dfb
       , group "encode"   (nf encode d)
Packit 9a2dfb
                          (nf encode d')
Packit 9a2dfb
       , group "fromJSON" (nf (  fromJSON :: FJ T ) v)
Packit 9a2dfb
                          (nf (  fromJSON :: FJ T') v)
Packit 9a2dfb
       ]
Packit 9a2dfb
  , let v = thBigRecordToJSON bigRecord
Packit 9a2dfb
    in bigRecord `deepseq` v `deepseq`
Packit 9a2dfb
       bgroup "BigRecord"
Packit 9a2dfb
       [ group "toJSON"   (nf thBigRecordToJSON bigRecord)
Packit 9a2dfb
                          (nf  gBigRecordToJSON bigRecord)
Packit 9a2dfb
       , group "encode"   (nf thBigRecordEncode bigRecord)
Packit 9a2dfb
                          (nf  gBigRecordEncode bigRecord)
Packit 9a2dfb
       , group "fromJSON" (nf (thBigRecordFromJSON :: FJ BigRecord) v)
Packit 9a2dfb
                          (nf ( gBigRecordFromJSON :: FJ BigRecord) v)
Packit 9a2dfb
       ]
Packit 9a2dfb
  , let v = thBigProductToJSON bigProduct
Packit 9a2dfb
    in bigProduct `deepseq` v `deepseq`
Packit 9a2dfb
       bgroup "BigProduct"
Packit 9a2dfb
       [ group "toJSON"   (nf thBigProductToJSON bigProduct)
Packit 9a2dfb
                          (nf gBigProductToJSON  bigProduct)
Packit 9a2dfb
       , group "encode"   (nf thBigProductEncode bigProduct)
Packit 9a2dfb
                          (nf  gBigProductEncode bigProduct)
Packit 9a2dfb
       , group "fromJSON" (nf (thBigProductFromJSON :: FJ BigProduct) v)
Packit 9a2dfb
                          (nf (gBigProductFromJSON  :: FJ BigProduct) v)
Packit 9a2dfb
       ]
Packit 9a2dfb
  , let v = thBigSumToJSON bigSum
Packit 9a2dfb
    in bigSum `deepseq` v `deepseq`
Packit 9a2dfb
       bgroup "BigSum"
Packit 9a2dfb
       [ group "toJSON"   (nf thBigSumToJSON bigSum)
Packit 9a2dfb
                          (nf gBigSumToJSON  bigSum)
Packit 9a2dfb
       , group "encode"   (nf thBigSumEncode bigSum)
Packit 9a2dfb
                          (nf  gBigSumEncode bigSum)
Packit 9a2dfb
       , group "fromJSON" (nf (thBigSumFromJSON :: FJ BigSum) v)
Packit 9a2dfb
                          (nf (gBigSumFromJSON  :: FJ BigSum) v)
Packit 9a2dfb
       ]
Packit 9a2dfb
  ]
Packit 9a2dfb
Packit 9a2dfb
group n th gen = bgroup n [ bench "th"      th
Packit 9a2dfb
                          , bench "generic" gen
Packit 9a2dfb
                          ]
Packit 9a2dfb
Packit 9a2dfb
sanityCheck = do
Packit 9a2dfb
  check d toJSON fromJSON encode
Packit 9a2dfb
  check d' toJSON fromJSON encode
Packit 9a2dfb
  check bigRecord thBigRecordToJSON thBigRecordFromJSON thBigRecordEncode
Packit 9a2dfb
  check bigRecord gBigRecordToJSON gBigRecordFromJSON gBigRecordEncode
Packit 9a2dfb
  check bigProduct thBigProductToJSON thBigProductFromJSON thBigProductEncode
Packit 9a2dfb
  check bigProduct gBigProductToJSON gBigProductFromJSON gBigProductEncode
Packit 9a2dfb
  check bigSum thBigSumToJSON thBigSumFromJSON thBigSumEncode
Packit 9a2dfb
  check bigSum gBigSumToJSON gBigSumFromJSON gBigSumEncode
Packit 9a2dfb
Packit 9a2dfb
check :: (Show a, Eq a)
Packit 9a2dfb
      => a -> (a -> Value) -> (Value -> Result a) -> (a -> ByteString) -> IO ()
Packit 9a2dfb
check x toJSON fromJSON encode = do
Packit 9a2dfb
  unless (Success x == (fromJSON . toJSON) x) $ fail $ "toJSON: " ++ show x
Packit 9a2dfb
  unless (Success x == (decode' . encode) x) $ fail $ "encode: " ++ show x
Packit 9a2dfb
  where
Packit 9a2dfb
    decode' s = case decode s of
Packit 9a2dfb
      Just v -> fromJSON v
Packit 9a2dfb
      Nothing -> fail ""
Packit 9a2dfb
Packit 9a2dfb
main = do
Packit 9a2dfb
  sanityCheck
Packit 9a2dfb
  runBench