on master help sign in
Add benchmarks for Serialize module
commit0957cd651615210b4c24280dbd2a31f54c8387ab authorHarendra Kumar <harendra@composewell.com> dateWed 9 Aug 2023, 00:57 (3 years ago) parent36be828
2 files changed+150
benchmark/Streamly/Benchmark/Data/Serialize.hs+144 benchmark/streamly-benchmarks.cabal+6
benchmark/Streamly/Benchmark/Data/Serialize.hsnew file+144
@@ -0,0 +1,144 @@
1+{-# LANGUAGE TemplateHaskell #-}
2+
3+#undef FUSION_CHECK
4+#ifdef FUSION_CHECK
5+{-# OPTIONS_GHC -ddump-simpl -ddump-to-file -dsuppress-all #-}
6+#endif
7+
8+-- |
9+-- Module : Streamly.Benchmark.Data.Serialize
10+-- Copyright : (c) 2023 Composewell
11+-- License : BSD-3-Clause
12+-- Maintainer : streamly@composewell.com
13+
14+module Main (main) where
15+
16+-------------------------------------------------------------------------------
17+-- Imports
18+-------------------------------------------------------------------------------
19+
20+import Control.DeepSeq (NFData(..))
21+import Control.Exception (assert)
22+import Control.Monad (replicateM_)
23+import GHC.Generics (Generic)
24+import System.Random (randomRIO)
25+
26+import Streamly.Internal.Data.Unbox (newBytes)
27+import Streamly.Internal.Data.Serialize
28+#define USE_TH
29+#ifdef USE_TH
30+import Streamly.Internal.Data.Serialize.TH
31+#endif
32+
33+import Gauge
34+import Streamly.Benchmark.Common
35+
36+-------------------------------------------------------------------------------
37+-- Types
38+-------------------------------------------------------------------------------
39+
40+data CustomDT1
41+ = CDT1C1
42+ | CDT1C2 Int
43+ | CDT1C3 Int Bool
44+ deriving (Generic, Show, Eq)
45+
46+#ifndef USE_TH
47+instance Serialize CustomDT1
48+#else
49+$(deriveSerialize ''CustomDT1)
50+#endif
51+
52+-------------------------------------------------------------------------------
53+-- Helpers
54+-------------------------------------------------------------------------------
55+
56+{-# INLINE pokeTimes #-}
57+pokeTimes :: forall a. Serialize a => a -> Int -> IO ()
58+pokeTimes val times = do
59+ let n =
60+ case size :: Size a of
61+ ConstSize x -> x
62+ VarSize f -> f val
63+ arr <- newBytes n
64+ replicateM_ times $ do
65+ serialize 0 arr val
66+
67+{-# INLINE peekTimes #-}
68+peekTimes :: forall a. Serialize a => a -> Int -> IO ()
69+peekTimes val times = do
70+ let n =
71+ case size :: Size a of
72+ ConstSize x -> x
73+ VarSize f -> f val
74+ arr <- newBytes n
75+ _ <- serialize 0 arr val
76+ replicateM_ times $ do
77+ (_, _ :: a) <- deserialize 0 arr
78+ return ()
79+
80+{-# INLINE roundtrip #-}
81+roundtrip :: forall a. (Eq a, Serialize a) => a -> Int -> IO ()
82+roundtrip val times = do
83+ let n =
84+ case size :: Size a of
85+ ConstSize x -> x
86+ VarSize f -> f val
87+ arr <- newBytes n
88+ replicateM_ times $ do
89+ _ <- serialize 0 arr val
90+ (_, val1) <- deserialize 0 arr
91+ assert (val == val1) (pure ())
92+
93+benchSink :: NFData b => String -> Int -> (Int -> IO b) -> Benchmark
94+benchSink name times f = bench name (nfIO (randomRIO (times, times) >>= f))
95+
96+-------------------------------------------------------------------------------
97+-- Benchmarks
98+-------------------------------------------------------------------------------
99+
100+allBenchmarks :: Int -> [Benchmark]
101+allBenchmarks times =
102+ [ bgroup "poke"
103+ [ benchSink "C1" times
104+ (pokeTimes (CDT1C1 :: CustomDT1))
105+ , benchSink "C2" times
106+ (pokeTimes ((CDT1C2 (5 :: Int)) :: CustomDT1))
107+ , benchSink "C3" times
108+ (pokeTimes ((CDT1C3 (5 :: Int) True) :: CustomDT1))
109+ ]
110+ , bgroup "peek"
111+ [ benchSink "C1" times
112+ (peekTimes (CDT1C1 :: CustomDT1))
113+ , benchSink "C2" times
114+ (peekTimes ((CDT1C2 (5 :: Int)) :: CustomDT1))
115+ , benchSink "C3" times
116+ (peekTimes ((CDT1C3 (5 :: Int) True) :: CustomDT1))
117+ ]
118+ , bgroup "roundtrip"
119+ [ benchSink "C1" times
120+ (roundtrip (CDT1C1 :: CustomDT1))
121+ , benchSink "C2" times
122+ (roundtrip ((CDT1C2 (5 :: Int)) :: CustomDT1))
123+ , benchSink "C3" times
124+ (roundtrip ((CDT1C3 (5 :: Int) True) :: CustomDT1))
125+ ]
126+ ]
127+
128+-------------------------------------------------------------------------------
129+-- Driver
130+-------------------------------------------------------------------------------
131+
132+main :: IO ()
133+main = do
134+#ifndef FUSION_CHECK
135+ runWithCLIOpts defaultStreamSize allBenchmarks
136+#else
137+ -- Enable FUSION_CHECK macro at the beginning of the file
138+ -- Enable one benchmark below, and run the benchmark
139+ -- Check the .dump-simpl output
140+ let value = 100000
141+ -- peekTimes ((CDT1C2 (5 :: Int)) :: CustomDT1) value
142+ roundtrip ((CDT1C2 (5 :: Int)) :: CustomDT1) value
143+ return ()
144+#endif
benchmark/streamly-benchmarks.cabal+6
@@ -369,6 +369,12 @@ benchmark Data.Unbox.Derive.TH
369369 cpp-options: -DUSE_TH
370370 main-is: Streamly/Benchmark/Data/Unbox.hs
371371
372+benchmark Data.Serialize
373+ import: bench-options
374+ type: exitcode-stdio-1.0
375+ hs-source-dirs: .
376+ main-is: Streamly/Benchmark/Data/Serialize.hs
377+
372378benchmark Data.Unfold
373379 import: bench-options
374380 type: exitcode-stdio-1.0