on master help sign in
Make aeson-benchmark-typed compare to old aeson
commit0849c2d1281275f37490d49b8c8da50ed84a4a10 authorOleg Grenrus <oleg.grenrus@iki.fi> dateFri 15 Jul 2016, 20:11 (10 years ago) parent5459273
10 files changed+251−34
benchmarks/AesonParse.hs+2−1 benchmarks/Compare.hs+2−1 benchmarks/Typed/Common.hs+7 benchmarks/Typed/Generic.hs+22−10 benchmarks/Typed/Manual.hs+22−10 benchmarks/Typed/TH.hs+22−9 benchmarks/aeson-benchmarks.cabal+4 examples/Twitter/Generic.hs+22−1 examples/Twitter/Manual.hs+134−1 examples/Twitter/TH.hs+14−1
benchmarks/AesonParse.hs+2−1
@@ -1,8 +1,9 @@
11{-# LANGUAGE BangPatterns, OverloadedStrings #-}
2+{-# LANGUAGE PackageImports #-}
23
34import Control.Exception
45import Control.Monad
5−import Data.Aeson
6+import "aeson-benchmarks" Data.Aeson
67import Data.Attoparsec.ByteString (IResult(..), parseWith)
78import Data.Time.Clock
89import System.Environment (getArgs)
benchmarks/Compare.hs+2−1
@@ -1,4 +1,5 @@
11{-# LANGUAGE ScopedTypeVariables #-}
2+{-# LANGUAGE PackageImports #-}
23
34module Main (main) where
45
@@ -11,7 +12,7 @@ import Twitter
1112import Twitter.Manual ()
1213import Typed.Common
1314import qualified Compare.JsonBench as JsonBench
14−import qualified Data.Aeson as Aeson
15+import qualified "aeson-benchmarks" Data.Aeson as Aeson
1516
1617main :: IO ()
1718main =
benchmarks/Typed/Common.hs+7
@@ -1,6 +1,13 @@
1+{-# LANGUAGE CPP, PackageImports #-}
12module Typed.Common (load) where
23
4+#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
35import Data.Aeson hiding (Result)
6+#else
7+import "aeson" Data.Aeson hiding (Result)
8+import qualified "aeson-benchmarks" Data.Aeson as B
9+#endif
10+
411import Data.ByteString.Lazy as L
512import Control.Applicative
613import System.IO
benchmarks/Typed/Generic.hs+22−10
@@ -1,29 +1,41 @@
1+{-# LANGUAGE PackageImports #-}
12module Typed.Generic (benchmarks) where
23
4+import "aeson" Data.Aeson hiding (Result)
5+import qualified "aeson-benchmarks" Data.Aeson as B
6+
37import Control.Applicative
48import Criterion
5−import Data.Aeson hiding (Result)
6−import Data.ByteString.Builder as B
79import Data.ByteString.Lazy as L
810import Twitter.TH
911import Typed.Common
1012
11−encodeDirect :: Result -> L.ByteString
12−encodeDirect = encode
13+encodeDirectA :: Result -> L.ByteString
14+encodeDirectA = encode
15+
16+encodeViaValueA :: Result -> L.ByteString
17+encodeViaValueA = encode . toJSON
18+
19+encodeDirectB :: Result -> L.ByteString
20+encodeDirectB = B.encode
1321
14−encodeViaValue :: Result -> L.ByteString
15−encodeViaValue = encode . toJSON
22+encodeViaValueB :: Result -> L.ByteString
23+encodeViaValueB = B.encode . B.toJSON
1624
1725benchmarks :: Benchmark
1826benchmarks =
1927 env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
2028 bgroup "generic" [
2129 bgroup "direct" [
22− bench "twitter100" $ nf encodeDirect twitter100
23− , bench "jp100" $ nf encodeDirect jp100
30+ bench "twitter100" $ nf encodeDirectB twitter100
31+ , bench "jp100" $ nf encodeDirectB jp100
32+ , bench "twitter100 baseline" $ nf encodeDirectA twitter100
33+ , bench "jp100 baseline" $ nf encodeDirectA jp100
2434 ]
2535 , bgroup "viaValue" [
26− bench "twitter100" $ nf encodeViaValue twitter100
27− , bench "jp100" $ nf encodeViaValue jp100
36+ bench "twitter100" $ nf encodeViaValueB twitter100
37+ , bench "jp100" $ nf encodeViaValueB jp100
38+ , bench "twitter100 baseline" $ nf encodeViaValueA twitter100
39+ , bench "jp100 baseline" $ nf encodeViaValueA jp100
2840 ]
2941 ]
benchmarks/Typed/Manual.hs+22−10
@@ -1,29 +1,41 @@
1+{-# LANGUAGE PackageImports #-}
12module Typed.Manual (benchmarks) where
23
4+import "aeson" Data.Aeson hiding (Result)
5+import qualified "aeson-benchmarks" Data.Aeson as B
6+
37import Control.Applicative
48import Criterion
5−import Data.Aeson hiding (Result)
6−import Data.ByteString.Builder as B
79import Data.ByteString.Lazy as L
810import Twitter.Manual
911import Typed.Common
1012
11−encodeDirect :: Result -> L.ByteString
12−encodeDirect = encode
13+encodeDirectA :: Result -> L.ByteString
14+encodeDirectA = encode
15+
16+encodeViaValueA :: Result -> L.ByteString
17+encodeViaValueA = encode . toJSON
18+
19+encodeDirectB :: Result -> L.ByteString
20+encodeDirectB = B.encode
1321
14−encodeViaValue :: Result -> L.ByteString
15−encodeViaValue = encode . toJSON
22+encodeViaValueB :: Result -> L.ByteString
23+encodeViaValueB = B.encode . B.toJSON
1624
1725benchmarks :: Benchmark
1826benchmarks =
1927 env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
2028 bgroup "manual" [
2129 bgroup "direct" [
22− bench "twitter100" $ nf encodeDirect twitter100
23− , bench "jp100" $ nf encodeDirect jp100
30+ bench "twitter100" $ nf encodeDirectB twitter100
31+ , bench "jp100" $ nf encodeDirectB jp100
32+ , bench "twitter100 baseline" $ nf encodeDirectA twitter100
33+ , bench "jp100 baseline" $ nf encodeDirectA jp100
2434 ]
2535 , bgroup "viaValue" [
26− bench "twitter100" $ nf encodeViaValue twitter100
27− , bench "jp100" $ nf encodeViaValue jp100
36+ bench "twitter100" $ nf encodeViaValueB twitter100
37+ , bench "jp100" $ nf encodeViaValueB jp100
38+ , bench "twitter100 baseline" $ nf encodeViaValueA twitter100
39+ , bench "jp100 baseline" $ nf encodeViaValueA jp100
2840 ]
2941 ]
benchmarks/Typed/TH.hs+22−9
@@ -1,29 +1,42 @@
1+{-# LANGUAGE PackageImports #-}
12module Typed.TH (benchmarks) where
23
4+import "aeson" Data.Aeson hiding (Result)
5+import qualified "aeson-benchmarks" Data.Aeson as B
6+
37import Control.Applicative
48import Criterion
5−import Data.Aeson hiding (Result)
69import Data.ByteString.Builder as B
710import Data.ByteString.Lazy as L
811import Twitter.TH
912import Typed.Common
1013
11−encodeDirect :: Result -> L.ByteString
12−encodeDirect = encode
14+encodeDirectA :: Result -> L.ByteString
15+encodeDirectA = encode
16+
17+encodeViaValueA :: Result -> L.ByteString
18+encodeViaValueA = encode . toJSON
19+
20+encodeDirectB :: Result -> L.ByteString
21+encodeDirectB = B.encode
1322
14−encodeViaValue :: Result -> L.ByteString
15−encodeViaValue = encode . toJSON
23+encodeViaValueB :: Result -> L.ByteString
24+encodeViaValueB = B.encode . B.toJSON
1625
1726benchmarks :: Benchmark
1827benchmarks =
1928 env ((,) <$> load "json-data/twitter100.json" <*> load "json-data/jp100.json") $ \ ~(twitter100, jp100) ->
2029 bgroup "th" [
2130 bgroup "direct" [
22− bench "twitter100" $ nf encodeDirect twitter100
23− , bench "jp100" $ nf encodeDirect jp100
31+ bench "twitter100" $ nf encodeDirectB twitter100
32+ , bench "jp100" $ nf encodeDirectB jp100
33+ , bench "twitter100 baseline" $ nf encodeDirectA twitter100
34+ , bench "jp100 baseline" $ nf encodeDirectA jp100
2435 ]
2536 , bgroup "viaValue" [
26− bench "twitter100" $ nf encodeViaValue twitter100
27− , bench "jp100" $ nf encodeViaValue jp100
37+ bench "twitter100" $ nf encodeViaValueA twitter100
38+ , bench "jp100" $ nf encodeViaValueA jp100
39+ , bench "twitter100 baseline" $ nf encodeViaValueB twitter100
40+ , bench "jp100 baseline" $ nf encodeViaValueB jp100
2841 ]
2942 ]
benchmarks/aeson-benchmarks.cabal+4
@@ -106,7 +106,11 @@ executable aeson-benchmark-typed
106106 main-is: Typed.hs
107107 hs-source-dirs: ../examples .
108108 ghc-options: -Wall -O2 -rtsopts
109+ -- We must help ourself in situations when there is both
110+ -- aeson and aeson-benchmakrs
111+ cpp-options: -DHAS_BOTH_AESON_AND_BENCHMARKS
109112 build-depends:
113+ aeson,
110114 aeson-benchmarks,
111115 base,
112116 criterion >= 1.0,
examples/Twitter/Generic.hs+22−1
@@ -1,5 +1,6 @@
11-- Use GHC generics to automatically generate good instances.
22
3+{-# LANGUAGE CPP, PackageImports #-}
34{-# OPTIONS_GHC -fno-warn-orphans #-}
45
56module Twitter.Generic
@@ -10,9 +11,15 @@ module Twitter.Generic
1011 , Result(..)
1112 ) where
1213
13−import Data.Aeson (ToJSON, FromJSON)
1414import Twitter
1515
16+#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
17+import Data.Aeson (ToJSON, FromJSON)
18+#else
19+import "aeson" Data.Aeson (ToJSON, FromJSON)
20+import qualified "aeson-benchmarks" Data.Aeson as B
21+#endif
22+
1623instance ToJSON Metadata
1724instance FromJSON Metadata
1825
@@ -24,3 +31,17 @@ instance FromJSON Story
2431
2532instance ToJSON Result
2633instance FromJSON Result
34+
35+#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
36+instance B.ToJSON Metadata
37+instance B.FromJSON Metadata
38+
39+instance B.ToJSON Geo
40+instance B.FromJSON Geo
41+
42+instance B.ToJSON Story
43+instance B.FromJSON Story
44+
45+instance B.ToJSON Result
46+instance B.FromJSON Result
47+#endif
examples/Twitter/Manual.hs+134−1
@@ -1,5 +1,6 @@
11-- Manually write instances.
22
3+{-# LANGUAGE CPP, PackageImports #-}
34{-# LANGUAGE OverloadedStrings, RecordWildCards #-}
45{-# OPTIONS_GHC -fno-warn-orphans #-}
56
@@ -12,12 +13,19 @@ module Twitter.Manual
1213 ) where
1314
1415import Control.Applicative
15−import Data.Aeson hiding (Result)
1616import Data.Monoid ((<>))
1717import Prelude hiding (id)
1818import Twitter
1919
20+#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
21+import Data.Aeson hiding (Result)
22+#else
23+import "aeson" Data.Aeson hiding (Result)
24+import qualified "aeson-benchmarks" Data.Aeson as B
25+#endif
26+
2027instance ToJSON Metadata where
28+
2129 toJSON Metadata{..} = object [
2230 "result_type" .= result_type
2331 ]
@@ -139,3 +147,128 @@ instance FromJSON Result where
139147 <*> v .: "max_id_str"
140148 <*> v .: "query"
141149 parseJSON _ = empty
150+
151+#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
152+instance B.ToJSON Metadata where
153+ toJSON Metadata{..} = B.object [
154+ "result_type" B..= result_type
155+ ]
156+
157+ toEncoding Metadata{..} = B.pairs $
158+ "result_type" B..= result_type
159+
160+instance B.FromJSON Metadata where
161+ parseJSON (B.Object v) = Metadata <$> v B..: "result_type"
162+ parseJSON _ = empty
163+
164+instance B.ToJSON Geo where
165+ toJSON Geo{..} = B.object [
166+ "type_" B..= type_
167+ , "coordinates" B..= coordinates
168+ ]
169+
170+ toEncoding Geo{..} = B.pairs $
171+ "type_" B..= type_
172+ <> "coordinates" B..= coordinates
173+
174+instance B.FromJSON Geo where
175+ parseJSON (B.Object v) = Geo <$>
176+ v B..: "type_"
177+ <*> v B..: "coordinates"
178+ parseJSON _ = empty
179+
180+instance B.ToJSON Story where
181+ toJSON Story{..} = B.object [
182+ "from_user_id_str" B..= from_user_id_str
183+ , "profile_image_url" B..= profile_image_url
184+ , "created_at" B..= created_at
185+ , "from_user" B..= from_user
186+ , "id_str" B..= id_str
187+ , "metadata" B..= metadata
188+ , "to_user_id" B..= to_user_id
189+ , "text" B..= text
190+ , "id" B..= id
191+ , "from_user_id" B..= from_user_id
192+ , "geo" B..= geo
193+ , "iso_language_code" B..= iso_language_code
194+ , "to_user_id_str" B..= to_user_id_str
195+ , "source" B..= source
196+ ]
197+
198+ toEncoding Story{..} = B.pairs $
199+ "from_user_id_str" B..= from_user_id_str
200+ <> "profile_image_url" B..= profile_image_url
201+ <> "created_at" B..= created_at
202+ <> "from_user" B..= from_user
203+ <> "id_str" B..= id_str
204+ <> "metadata" B..= metadata
205+ <> "to_user_id" B..= to_user_id
206+ <> "text" B..= text
207+ <> "id" B..= id
208+ <> "from_user_id" B..= from_user_id
209+ <> "geo" B..= geo
210+ <> "iso_language_code" B..= iso_language_code
211+ <> "to_user_id_str" B..= to_user_id_str
212+ <> "source" B..= source
213+
214+instance B.FromJSON Story where
215+ parseJSON (B.Object v) = Story <$>
216+ v B..: "from_user_id_str"
217+ <*> v B..: "profile_image_url"
218+ <*> v B..: "created_at"
219+ <*> v B..: "from_user"
220+ <*> v B..: "id_str"
221+ <*> v B..: "metadata"
222+ <*> v B..: "to_user_id"
223+ <*> v B..: "text"
224+ <*> v B..: "id"
225+ <*> v B..: "from_user_id"
226+ <*> v B..: "geo"
227+ <*> v B..: "iso_language_code"
228+ <*> v B..: "to_user_id_str"
229+ <*> v B..: "source"
230+ parseJSON _ = empty
231+
232+instance B.ToJSON Result where
233+ toJSON Result{..} = B.object [
234+ "results" B..= results
235+ , "max_id" B..= max_id
236+ , "since_id" B..= since_id
237+ , "refresh_url" B..= refresh_url
238+ , "next_page" B..= next_page
239+ , "results_per_page" B..= results_per_page
240+ , "page" B..= page
241+ , "completed_in" B..= completed_in
242+ , "since_id_str" B..= since_id_str
243+ , "max_id_str" B..= max_id_str
244+ , "query" B..= query
245+ ]
246+
247+ toEncoding Result{..} = B.pairs $
248+ "results" B..= results
249+ <> "max_id" B..= max_id
250+ <> "since_id" B..= since_id
251+ <> "refresh_url" B..= refresh_url
252+ <> "next_page" B..= next_page
253+ <> "results_per_page" B..= results_per_page
254+ <> "page" B..= page
255+ <> "completed_in" B..= completed_in
256+ <> "since_id_str" B..= since_id_str
257+ <> "max_id_str" B..= max_id_str
258+ <> "query" B..= query
259+
260+instance B.FromJSON Result where
261+ parseJSON (B.Object v) = Result <$>
262+ v B..: "results"
263+ <*> v B..: "max_id"
264+ <*> v B..: "since_id"
265+ <*> v B..: "refresh_url"
266+ <*> v B..: "next_page"
267+ <*> v B..: "results_per_page"
268+ <*> v B..: "page"
269+ <*> v B..: "completed_in"
270+ <*> v B..: "since_id_str"
271+ <*> v B..: "max_id_str"
272+ <*> v B..: "query"
273+ parseJSON _ = empty
274+#endif
examples/Twitter/TH.hs+14−1
@@ -1,5 +1,6 @@
11-- Use Template Haskell to generate good instances.
22
3+{-# LANGUAGE CPP, PackageImports #-}
34{-# LANGUAGE TemplateHaskell #-}
45{-# OPTIONS_GHC -fno-warn-orphans #-}
56
@@ -10,11 +11,23 @@ module Twitter.TH
1011 , Story(..)
1112 , Result(..)
1213 ) where
14+import Twitter
1315
16+#ifndef HAS_BOTH_AESON_AND_BENCHMARKS
1417import Data.Aeson.TH
15−import Twitter
18+#else
19+import "aeson" Data.Aeson.TH
20+import qualified "aeson-benchmarks" Data.Aeson.TH as B
21+#endif
1622
1723$(deriveJSON defaultOptions ''Metadata)
1824$(deriveJSON defaultOptions ''Geo)
1925$(deriveJSON defaultOptions ''Story)
2026$(deriveJSON defaultOptions ''Result)
27+
28+#ifdef HAS_BOTH_AESON_AND_BENCHMARKS
29+$(B.deriveJSON B.defaultOptions ''Metadata)
30+$(B.deriveJSON B.defaultOptions ''Geo)
31+$(B.deriveJSON B.defaultOptions ''Story)
32+$(B.deriveJSON B.defaultOptions ''Result)
33+#endif