on master help sign in
Add a benchmark comparing against the json-builder package

Surprisingly to me, json-builder performs very poorly: it's slightly slower than aeson's old encode implementation, and takes about 3x as much memory.

commite424289def457e0642148f53d4ec361971257251 authorBryan O'Sullivan <bos@serpentine.com> dateTue 7 Jul 2015, 16:56 (11 years ago) parent0fb760c
4 files changed+98
aeson.cabal+1 benchmarks/Compare.hs+17 benchmarks/Compare/JsonBuilder.hs+65 benchmarks/aeson-benchmarks.cabal+15
aeson.cabal+1
@@ -64,6 +64,7 @@ extra-source-files:
6464 benchmarks/*.cabal
6565 benchmarks/*.hs
6666 benchmarks/*.py
67+ benchmarks/Compare/*.hs
6768 benchmarks/Makefile
6869 benchmarks/Typed/*.hs
6970 benchmarks/json-data/*.json
benchmarks/Compare.hsnew file+17
@@ -0,0 +1,17 @@
1+module Main (main) where
2+
3+import Criterion.Main
4+import Data.Json.Builder
5+import Compare.JsonBuilder ()
6+import Twitter
7+import Twitter.Manual ()
8+import Typed.Common
9+import qualified Data.Aeson as Aeson
10+
11+main :: IO ()
12+main = do
13+ twtr <- load "json-data/twitter100.json" :: IO Result
14+ defaultMain [
15+ bench "aeson" $ nf Aeson.encode twtr
16+ , bench "json-builder" $ nf toJsonLBS twtr
17+ ]
benchmarks/Compare/JsonBuilder.hsnew file+65
@@ -0,0 +1,65 @@
1+{-# LANGUAGE RecordWildCards #-}
2+{-# OPTIONS_GHC -fno-warn-orphans #-}
3+
4+module Compare.JsonBuilder () where
5+
6+import Data.Json.Builder
7+import Data.Monoid ((<>))
8+import Prelude hiding (id)
9+import Twitter
10+import Twitter.Manual ()
11+
12+instance JsObject Metadata where
13+ toObject Metadata{..} = row "result_type" result_type
14+
15+instance Value Metadata where
16+ toJson = toJson . toObject
17+
18+instance JsObject Geo where
19+ toObject Geo{..} =
20+ row "type_" type_ <>
21+ row "coordinates" coordinates
22+
23+instance Value Geo where
24+ toJson = toJson . toObject
25+
26+instance Value a => Value (Maybe a) where
27+ toJson (Just a) = toJson a
28+ toJson Nothing = jsNull
29+
30+instance JsObject Story where
31+ toObject Story{..} =
32+ row "from_user_id_str" from_user_id_str <>
33+ row "profile_image_url" profile_image_url <>
34+ row "created_at" created_at <>
35+ row "from_user" from_user <>
36+ row "id_str" id_str <>
37+ row "metadata" metadata <>
38+ row "to_user_id" to_user_id <>
39+ row "text" text <>
40+ row "id" id <>
41+ row "from_user_id" from_user_id <>
42+ row "geo" geo <>
43+ row "iso_language_code" iso_language_code <>
44+ row "to_user_id_str" to_user_id_str <>
45+ row "source" source
46+
47+instance Value Story where
48+ toJson = toJson . toObject
49+
50+instance JsObject Result where
51+ toObject Result{..} =
52+ row "results" results <>
53+ row "max_id" max_id <>
54+ row "since_id" since_id <>
55+ row "refresh_url" refresh_url <>
56+ row "next_page" next_page <>
57+ row "results_per_page" results_per_page <>
58+ row "page" page <>
59+ row "completed_in" completed_in <>
60+ row "since_id_str" since_id_str <>
61+ row "max_id_str" max_id_str <>
62+ row "query" query
63+
64+instance Value Result where
65+ toJson = toJson . toObject
benchmarks/aeson-benchmarks.cabal+15
@@ -55,6 +55,21 @@ library
5555 ghc-options: -O2 -Wall
5656 cpp-options: -DGENERICS
5757
58+executable aeson-benchmark-compare
59+ main-is: Compare.hs
60+ hs-source-dirs: ../examples .
61+ ghc-options: -Wall -O2 -rtsopts
62+ build-depends:
63+ aeson-benchmarks,
64+ base,
65+ bytestring,
66+ criterion >= 1.0,
67+ deepseq,
68+ ghc-prim,
69+ json-builder,
70+ text,
71+ time
72+
5873executable aeson-benchmark-micro
5974 main-is: Micro.hs
6075 hs-source-dirs: ../examples .