Skip to content

Commit 6306cec

Browse files
authored
Merge pull request #563 from phadej/benchmarks-fix-562
Benchmarks fix #562
2 parents 2bc6f22 + ad4bb7b commit 6306cec

File tree

13 files changed

+227
-49
lines changed

13 files changed

+227
-49
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ dist-newstyle
44
.cabal-sandbox/
55
cabal.sandbox.config
66
.stack-work/
7+
.stack-work-bench/
78

89
*.o
910
*.hi

benchmarks/AesonMap.hs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ benchDecodeHM name val = bgroup name
160160
, bench "Identity" $ nf (decodeHMB proxyT1) val
161161
, bench "Coerce" $ nf (decodeHMB proxyT2) val
162162
, bench "Parser" $ nf (decodeHMB proxyT3) val
163-
, bench "aeson-0.11" $ nf (decodeHMA proxyText) val
163+
, bench "aeson-hackage" $ nf (decodeHMA proxyText) val
164164
, bench "Tagged Text" $ nf (decodeHMB $ proxyTagged proxyText) val
165165
, bench "Tagged Identity" $ nf (decodeHMB $ proxyTagged proxyT1) val
166166
, bench "Tagged Coerce" $ nf (decodeHMB $ proxyTagged proxyT2) val
@@ -172,11 +172,11 @@ benchDecodeMap
172172
-> LBS.ByteString
173173
-> Benchmark
174174
benchDecodeMap name val = bgroup name
175-
[ bench "Text" $ nf (decodeMapB proxyText) val
176-
, bench "Identity" $ nf (decodeMapB proxyT1) val
177-
, bench "Coerce" $ nf (decodeMapB proxyT2) val
178-
, bench "Parser" $ nf (decodeMapB proxyT3) val
179-
, bench "aeson-0.11" $ nf (decodeMapA proxyText) val
175+
[ bench "Text" $ nf (decodeMapB proxyText) val
176+
, bench "Identity" $ nf (decodeMapB proxyT1) val
177+
, bench "Coerce" $ nf (decodeMapB proxyT2) val
178+
, bench "Parser" $ nf (decodeMapB proxyT3) val
179+
, bench "aeson-hackage" $ nf (decodeMapA proxyText) val
180180
]
181181

182182
benchEncodeHM

benchmarks/CompareWithJSON.hs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE PackageImports #-}
12
{-# OPTIONS_GHC -fno-warn-orphans #-}
23

34
module Main (main) where
@@ -10,8 +11,11 @@ import Blaze.ByteString.Builder.Char.Utf8 (fromString)
1011
import Control.DeepSeq (NFData(rnf))
1112
import Criterion.Main
1213
import Data.Maybe (fromMaybe)
13-
import qualified Data.Aeson as A
14-
import qualified Data.Aeson.Text as A
14+
import qualified "aeson-benchmarks" Data.Aeson as A
15+
import qualified "aeson-benchmarks" Data.Aeson.Text as A
16+
import qualified "aeson-benchmarks" Data.Aeson.Parser.Internal as I
17+
import qualified "aeson" Data.Aeson as B
18+
import qualified Data.ByteString as BS
1519
import qualified Data.ByteString.Lazy as BL
1620
import qualified Data.Text.Lazy as TL
1721
import qualified Data.Text.Lazy.Builder as TLB
@@ -41,6 +45,19 @@ decodeA s = fromMaybe (error "fail to parse via Aeson") $ A.decode s
4145
decodeA' :: BL.ByteString -> A.Value
4246
decodeA' s = fromMaybe (error "fail to parse via Aeson") $ A.decode' s
4347

48+
decodeAS :: BS.ByteString -> A.Value
49+
decodeAS s = fromMaybe (error "fail to parse via Aeson") $ A.decodeStrict' s
50+
51+
decodeB :: BL.ByteString -> B.Value
52+
decodeB s = fromMaybe (error "fail to parse via Aeson") $ B.decode s
53+
54+
decodeBS :: BS.ByteString -> B.Value
55+
decodeBS s = fromMaybe (error "fail to parse via Aeson") $ B.decodeStrict' s
56+
57+
decodeIP :: BL.ByteString -> A.Value
58+
decodeIP s = fromMaybe (error "fail to parse via Parser.decodeWith") $
59+
I.decodeWith I.jsonEOF A.fromJSON s
60+
4461
encodeJ :: J.JSValue -> BL.ByteString
4562
encodeJ = toLazyByteString . fromString . J.encode
4663

@@ -55,19 +72,27 @@ main = do
5572
let enFile = "json-data/twitter100.json"
5673
jpFile = "json-data/jp100.json"
5774
enA <- BL.readFile enFile
75+
enS <- BS.readFile enFile
5876
enJ <- readFile enFile
5977
jpA <- BL.readFile jpFile
78+
jpS <- BS.readFile jpFile
6079
jpJ <- readFile jpFile
6180
defaultMain [
6281
bgroup "decode" [
6382
bgroup "en" [
64-
bench "aeson/lazy" $ nf decodeA enA
65-
, bench "aeson/strict" $ nf decodeA' enA
66-
, bench "json" $ nf decodeJ enJ
83+
bench "aeson/lazy" $ nf decodeA enA
84+
, bench "aeson/strict" $ nf decodeA' enA
85+
, bench "aeson/stricter" $ nf decodeAS enS
86+
, bench "aeson/hackage" $ nf decodeB enA
87+
, bench "aeson/hackage'" $ nf decodeBS enS
88+
, bench "aeson/parser" $ nf decodeIP enA
89+
, bench "json" $ nf decodeJ enJ
6790
]
6891
, bgroup "jp" [
69-
bench "aeson" $ nf decodeA jpA
70-
, bench "json" $ nf decodeJ jpJ
92+
bench "aeson" $ nf decodeA jpA
93+
, bench "aeson/stricter" $ nf decodeAS jpS
94+
, bench "aeson/hackage" $ nf decodeB jpA
95+
, bench "json" $ nf decodeJ jpJ
7196
]
7297
]
7398
, bgroup "encode" [

benchmarks/Dates.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# OPTIONS_GHC -fsimpl-tick-factor=0 #-}
12
module Main (main) where
23

34
import Prelude ()

benchmarks/Typed.hs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ main = defaultMain [
1313
Generic.benchmarks
1414
, Manual.benchmarks
1515
, TH.benchmarks
16+
, Generic.decodeBenchmarks
17+
, Manual.decodeBenchmarks
18+
, TH.decodeBenchmarks
1619
]

benchmarks/Typed/Generic.hs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{-# LANGUAGE PackageImports #-}
2-
module Typed.Generic (benchmarks) where
2+
module Typed.Generic (benchmarks, decodeBenchmarks) where
33

44
import Prelude ()
55
import Prelude.Compat
66

77
import "aeson" Data.Aeson hiding (Result)
88
import Criterion
99
import Data.ByteString.Lazy as L
10-
import Twitter.TH
10+
import Twitter.Generic
1111
import Typed.Common
1212
import qualified "aeson-benchmarks" Data.Aeson as B
1313

@@ -26,7 +26,7 @@ encodeViaValueB = B.encode . B.toJSON
2626
benchmarks :: Benchmark
2727
benchmarks =
2828
env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
29-
bgroup "generic" [
29+
bgroup "encodeGeneric" [
3030
bgroup "direct" [
3131
bench "twitter100" $ nf encodeDirectB twitter100
3232
, bench "jp100" $ nf encodeDirectB jp100
@@ -40,3 +40,21 @@ benchmarks =
4040
, bench "jp100 baseline" $ nf encodeViaValueA jp100
4141
]
4242
]
43+
44+
decodeDirectA :: L.ByteString -> Maybe Result
45+
decodeDirectA = decode
46+
47+
decodeDirectB :: L.ByteString -> Maybe Result
48+
decodeDirectB = B.decode
49+
50+
decodeBenchmarks :: Benchmark
51+
decodeBenchmarks =
52+
env ((,) <$> L.readFile "json-data/twitter100.json" <*> L.readFile "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
53+
bgroup "decodeGeneric"
54+
[ bgroup "direct"
55+
[ bench "twitter100" $ nf decodeDirectB twitter100
56+
, bench "jp100" $ nf decodeDirectB jp100
57+
, bench "twitter100 baseline" $ nf decodeDirectA twitter100
58+
, bench "jp100 baseline" $ nf decodeDirectA jp100
59+
]
60+
]

benchmarks/Typed/Manual.hs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{-# LANGUAGE PackageImports #-}
2-
module Typed.Manual (benchmarks) where
2+
module Typed.Manual (benchmarks, decodeBenchmarks) where
33

44
import Prelude ()
55
import Prelude.Compat
@@ -26,7 +26,7 @@ encodeViaValueB = B.encode . B.toJSON
2626
benchmarks :: Benchmark
2727
benchmarks =
2828
env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
29-
bgroup "manual" [
29+
bgroup "encodeManual" [
3030
bgroup "direct" [
3131
bench "twitter100" $ nf encodeDirectB twitter100
3232
, bench "jp100" $ nf encodeDirectB jp100
@@ -40,3 +40,21 @@ benchmarks =
4040
, bench "jp100 baseline" $ nf encodeViaValueA jp100
4141
]
4242
]
43+
44+
decodeDirectA :: L.ByteString -> Maybe Result
45+
decodeDirectA = decode
46+
47+
decodeDirectB :: L.ByteString -> Maybe Result
48+
decodeDirectB = B.decode
49+
50+
decodeBenchmarks :: Benchmark
51+
decodeBenchmarks =
52+
env ((,) <$> L.readFile "json-data/twitter100.json" <*> L.readFile "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
53+
bgroup "decodeManual"
54+
[ bgroup "direct"
55+
[ bench "twitter100" $ nf decodeDirectB twitter100
56+
, bench "jp100" $ nf decodeDirectB jp100
57+
, bench "twitter100 baseline" $ nf decodeDirectA twitter100
58+
, bench "jp100 baseline" $ nf decodeDirectA jp100
59+
]
60+
]

benchmarks/Typed/TH.hs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{-# LANGUAGE PackageImports #-}
2-
module Typed.TH (benchmarks) where
2+
module Typed.TH (benchmarks, decodeBenchmarks) where
33

44
import Prelude ()
55
import Prelude.Compat
@@ -26,7 +26,7 @@ encodeViaValueB = B.encode . B.toJSON
2626
benchmarks :: Benchmark
2727
benchmarks =
2828
env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
29-
bgroup "th" [
29+
bgroup "encodeTH" [
3030
bgroup "direct" [
3131
bench "twitter100" $ nf encodeDirectB twitter100
3232
, bench "jp100" $ nf encodeDirectB jp100
@@ -40,3 +40,21 @@ benchmarks =
4040
, bench "jp100 baseline" $ nf encodeViaValueB jp100
4141
]
4242
]
43+
44+
decodeDirectA :: L.ByteString -> Maybe Result
45+
decodeDirectA = decode
46+
47+
decodeDirectB :: L.ByteString -> Maybe Result
48+
decodeDirectB = B.decode
49+
50+
decodeBenchmarks :: Benchmark
51+
decodeBenchmarks =
52+
env ((,) <$> L.readFile "json-data/twitter100.json" <*> L.readFile "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
53+
bgroup "decodeTH"
54+
[ bgroup "direct"
55+
[ bench "twitter100" $ nf decodeDirectB twitter100
56+
, bench "jp100" $ nf decodeDirectB jp100
57+
, bench "twitter100 baseline" $ nf decodeDirectA twitter100
58+
, bench "jp100 baseline" $ nf decodeDirectA jp100
59+
]
60+
]

benchmarks/aeson-benchmarks.cabal

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,13 @@ executable aeson-benchmark-compare
8383
main-is: Compare.hs
8484
hs-source-dirs: ../examples .
8585
ghc-options: -Wall -O2 -rtsopts
86+
other-modules:
87+
Compare.BufferBuilder
88+
Compare.JsonBench
89+
Compare.JsonBuilder
90+
Twitter
91+
Twitter.Manual
92+
Typed.Common
8693
build-depends:
8794
aeson-benchmarks,
8895
base,
@@ -116,6 +123,16 @@ executable aeson-benchmark-typed
116123
-- We must help ourself in situations when there is both
117124
-- aeson and aeson-benchmakrs
118125
cpp-options: -DHAS_BOTH_AESON_AND_BENCHMARKS
126+
other-modules:
127+
Twitter
128+
Twitter.Generic
129+
Twitter.Manual
130+
Twitter.Options
131+
Twitter.TH
132+
Typed.Common
133+
Typed.Generic
134+
Typed.Manual
135+
Typed.TH
119136
build-depends:
120137
aeson,
121138
aeson-benchmarks,
@@ -136,7 +153,9 @@ executable aeson-benchmark-typed
136153
executable aeson-benchmark-compare-with-json
137154
main-is: CompareWithJSON.hs
138155
ghc-options: -Wall -O2 -rtsopts
156+
cpp-options: -DHAS_BOTH_AESON_AND_BENCHMARKS
139157
build-depends:
158+
aeson,
140159
aeson-benchmarks,
141160
base,
142161
base-compat,

examples/Twitter/Generic.hs

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
-- Use GHC generics to automatically generate good instances.
2+
23
{-# LANGUAGE CPP #-}
34
{-# OPTIONS_GHC -fno-warn-orphans #-}
45

6+
#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
7+
{-# LANGUAGE PackageImports #-}
8+
#endif
9+
510
module Twitter.Generic
611
(
712
Metadata(..)
@@ -11,39 +16,64 @@ module Twitter.Generic
1116
) where
1217

1318
import Prelude ()
14-
import Prelude.Compat
19+
import Prelude.Compat ()
1520

1621
import Twitter
22+
import Twitter.Options
1723

1824
#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
19-
import Data.Aeson (ToJSON, FromJSON)
25+
import Data.Aeson (ToJSON (..), FromJSON (..), genericToJSON, genericToEncoding, genericParseJSON)
2026
#else
21-
import "aeson" Data.Aeson (ToJSON, FromJSON)
27+
import "aeson" Data.Aeson (ToJSON (..), FromJSON (..), genericToJSON, genericToEncoding, genericParseJSON)
2228
import qualified "aeson-benchmarks" Data.Aeson as B
2329
#endif
2430

25-
instance ToJSON Metadata
26-
instance FromJSON Metadata
31+
instance ToJSON Metadata where
32+
toJSON = genericToJSON twitterOptions
33+
toEncoding = genericToEncoding twitterOptions
34+
instance FromJSON Metadata where
35+
parseJSON = genericParseJSON twitterOptions
2736

28-
instance ToJSON Geo
29-
instance FromJSON Geo
37+
instance ToJSON Geo where
38+
toJSON = genericToJSON twitterOptions
39+
toEncoding = genericToEncoding twitterOptions
40+
instance FromJSON Geo where
41+
parseJSON = genericParseJSON twitterOptions
3042

31-
instance ToJSON Story
32-
instance FromJSON Story
43+
instance ToJSON Story where
44+
toJSON = genericToJSON twitterOptions
45+
toEncoding = genericToEncoding twitterOptions
46+
instance FromJSON Story where
47+
parseJSON = genericParseJSON twitterOptions
3348

34-
instance ToJSON Result
35-
instance FromJSON Result
49+
instance ToJSON Result where
50+
toJSON = genericToJSON twitterOptions
51+
toEncoding = genericToEncoding twitterOptions
52+
instance FromJSON Result where
53+
parseJSON = genericParseJSON twitterOptions
3654

3755
#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
38-
instance B.ToJSON Metadata
39-
instance B.FromJSON Metadata
56+
instance B.ToJSON Metadata where
57+
toJSON = B.genericToJSON btwitterOptions
58+
toEncoding = B.genericToEncoding btwitterOptions
59+
instance B.FromJSON Metadata where
60+
parseJSON = B.genericParseJSON btwitterOptions
4061

41-
instance B.ToJSON Geo
42-
instance B.FromJSON Geo
62+
instance B.ToJSON Geo where
63+
toJSON = B.genericToJSON btwitterOptions
64+
toEncoding = B.genericToEncoding btwitterOptions
65+
instance B.FromJSON Geo where
66+
parseJSON = B.genericParseJSON btwitterOptions
4367

44-
instance B.ToJSON Story
45-
instance B.FromJSON Story
68+
instance B.ToJSON Story where
69+
toJSON = B.genericToJSON btwitterOptions
70+
toEncoding = B.genericToEncoding btwitterOptions
71+
instance B.FromJSON Story where
72+
parseJSON = B.genericParseJSON btwitterOptions
4673

47-
instance B.ToJSON Result
48-
instance B.FromJSON Result
74+
instance B.ToJSON Result where
75+
toJSON = B.genericToJSON btwitterOptions
76+
toEncoding = B.genericToEncoding btwitterOptions
77+
instance B.FromJSON Result where
78+
parseJSON = B.genericParseJSON btwitterOptions
4979
#endif

0 commit comments

Comments
 (0)