|
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
|