on master help sign in
Compare encoding performance against buffer-builder

This result was surprising to me, as the buffer-builder authors claim it's all kinds of crazy fast. At least under GHC 7.10.1, aeson beats it handily, being 2x faster. On the other hand, buffer-builder allocates very little, 19x less than aeson.

commit388905044afe041431ca0274592d580c5cf4de56 authorBryan O'Sullivan <bos@serpentine.com> dateTue 7 Jul 2015, 17:18 (11 years ago) parente424289
4 files changed+63−1
benchmarks/Compare.hs+3 benchmarks/Compare/BufferBuilder.hs+59 benchmarks/Compare/JsonBuilder.hs−1 benchmarks/aeson-benchmarks.cabal+1
benchmarks/Compare.hs+3
@@ -2,6 +2,8 @@ module Main (main) where
22
33import Criterion.Main
44import Data.Json.Builder
5+import Data.BufferBuilder.Json
6+import Compare.BufferBuilder ()
57import Compare.JsonBuilder ()
68import Twitter
79import Twitter.Manual ()
@@ -13,5 +15,6 @@ main = do
1315 twtr <- load "json-data/twitter100.json" :: IO Result
1416 defaultMain [
1517 bench "aeson" $ nf Aeson.encode twtr
18+ , bench "buffer-builder" $ nf encodeJson twtr
1619 , bench "json-builder" $ nf toJsonLBS twtr
1720 ]
benchmarks/Compare/BufferBuilder.hsnew file+59
@@ -0,0 +1,59 @@
1+{-# LANGUAGE OverloadedStrings, RecordWildCards #-}
2+{-# OPTIONS_GHC -fno-warn-orphans #-}
3+
4+module Compare.BufferBuilder () where
5+
6+import Data.BufferBuilder.Json
7+import Data.Monoid ((<>))
8+import Data.Int (Int64)
9+import Prelude hiding (id)
10+import Twitter
11+import qualified Data.BufferBuilder.Utf8 as UB
12+
13+instance (ToJson a, ToJson b) => ToJson (a,b) where
14+ toJson (a,b) = array [toJson a, toJson b]
15+
16+instance ToJson Int64 where
17+ toJson a = unsafeValueUtf8Builder $
18+ UB.appendDecimalSignedInt (fromIntegral a)
19+ {-# INLINE toJson #-}
20+
21+instance ToJson Metadata where
22+ toJson Metadata{..} = toJson $
23+ "result_type" .= result_type
24+
25+instance ToJson Geo where
26+ toJson Geo{..} = toJson $
27+ "type_" .= type_
28+ <> "coordinates" .= coordinates
29+
30+instance ToJson Story where
31+ toJson Story{..} = toJson $
32+ "from_user_id_str" .= from_user_id_str
33+ <> "profile_image_url" .= profile_image_url
34+ <> "created_at" .= created_at
35+ <> "from_user" .= from_user
36+ <> "id_str" .= id_str
37+ <> "metadata" .= metadata
38+ <> "to_user_id" .= to_user_id
39+ <> "text" .= text
40+ <> "id" .= id
41+ <> "from_user_id" .= from_user_id
42+ <> "geo" .= geo
43+ <> "iso_language_code" .= iso_language_code
44+ <> "to_user_id_str" .= to_user_id_str
45+ <> "source" .= source
46+
47+instance ToJson Result where
48+ toJson Result{..} = toJson $
49+ "results" .= results
50+ <> "max_id" .= max_id
51+ <> "since_id" .= since_id
52+ <> "refresh_url" .= refresh_url
53+ <> "next_page" .= next_page
54+ <> "results_per_page" .= results_per_page
55+ <> "page" .= page
56+ <> "completed_in" .= completed_in
57+ <> "since_id_str" .= since_id_str
58+ <> "max_id_str" .= max_id_str
59+ <> "query" .= query
benchmarks/Compare/JsonBuilder.hs−1
@@ -7,7 +7,6 @@ import Data.Json.Builder
77import Data.Monoid ((<>))
88import Prelude hiding (id)
99import Twitter
10−import Twitter.Manual ()
1110
1211instance JsObject Metadata where
1312 toObject Metadata{..} = row "result_type" result_type
benchmarks/aeson-benchmarks.cabal+1
@@ -62,6 +62,7 @@ executable aeson-benchmark-compare
6262 build-depends:
6363 aeson-benchmarks,
6464 base,
65+ buffer-builder,
6566 bytestring,
6667 criterion >= 1.0,
6768 deepseq,