on master help sign in
Use deepseq instead of equality check
commit282d79cd9d70e30ed2c46fdb4ffe680e53a5e32d authorHarendra Kumar <harendra@composewell.com> dateTue 22 Aug 2023, 21:47 (3 years ago) parentb6a2d3e
1 file changed+74−12
benchmark/Streamly/Benchmark/Data/Serialize.hs+74−12
benchmark/Streamly/Benchmark/Data/Serialize.hs+74−12
@@ -17,7 +17,7 @@ module Main (main) where
1717-- Imports
1818-------------------------------------------------------------------------------
1919
20−import Control.DeepSeq (NFData(..))
20+import Control.DeepSeq (NFData(..), deepseq)
2121import GHC.Generics (Generic)
2222import System.Random (randomRIO)
2323#ifndef USE_UNBOX
@@ -70,6 +70,10 @@ instance SERIALIZE_CLASS Unit
7070$(DERIVE_CLASS ''Unit)
7171#endif
7272
73+instance NFData Unit where
74+ {-# INLINE rnf #-}
75+ rnf _ = ()
76+
7377data Sum2
7478 = Sum21
7579 | Sum22
@@ -81,6 +85,10 @@ instance SERIALIZE_CLASS Sum2
8185$(DERIVE_CLASS ''Sum2)
8286#endif
8387
88+instance NFData Sum2 where
89+ {-# INLINE rnf #-}
90+ rnf _ = ()
91+
8492data Sum25
8593 = Sum251
8694 | Sum252
@@ -115,6 +123,10 @@ instance SERIALIZE_CLASS Sum25
115123$(DERIVE_CLASS ''Sum25)
116124#endif
117125
126+instance NFData Sum25 where
127+ {-# INLINE rnf #-}
128+ rnf _ = ()
129+
118130data Product25
119131 = Product25
120132 Int
@@ -150,6 +162,37 @@ instance SERIALIZE_CLASS Product25
150162$(DERIVE_CLASS ''Product25)
151163#endif
152164
165+instance NFData Product25 where
166+ {-# INLINE rnf #-}
167+ rnf
168+ (Product25 a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20 a21 a22 a23 a24 a25)
169+ = a1
170+ `seq` a2
171+ `seq` a3
172+ `seq` a4
173+ `seq` a5
174+ `seq` a6
175+ `seq` a7
176+ `seq` a8
177+ `seq` a9
178+ `seq` a10
179+ `seq` a11
180+ `seq` a12
181+ `seq` a13
182+ `seq` a14
183+ `seq` a15
184+ `seq` a16
185+ `seq` a17
186+ `seq` a18
187+ `seq` a19
188+ `seq` a20
189+ `seq` a21
190+ `seq` a22
191+ `seq` a23
192+ `seq` a24
193+ `seq` a25
194+ `seq` ()
195+
153196-- XXX derived Eq instance is not inlined
154197instance Eq Product25 where
155198 {-# INLINE (==) #-}
@@ -198,6 +241,12 @@ instance SERIALIZE_CLASS CustomDT1
198241$(DERIVE_CLASS ''CustomDT1)
199242#endif
200243
244+instance NFData CustomDT1 where
245+ {-# INLINE rnf #-}
246+ rnf CDT1C1 = ()
247+ rnf (CDT1C2 i) = i `seq` ()
248+ rnf (CDT1C3 i1 i2) = i1 `seq` i2 `seq` ()
249+
201250-------------------------------------------------------------------------------
202251-- Recursive ADT
203252-------------------------------------------------------------------------------
@@ -215,6 +264,7 @@ $(deriveSerialize ''BinTree)
215264#endif
216265
217266instance NFData a => NFData (BinTree a) where
267+ {-# INLINE rnf #-}
218268 rnf (Leaf a) = rnf a `seq` ()
219269 rnf (Tree l r) = rnf l `seq` rnf r `seq` ()
220270
@@ -304,14 +354,17 @@ pokeTimes val times = do
304354 loopWith times poke arr val
305355
306356{-# INLINE peek #-}
307−peek :: forall a. (Eq a, SERIALIZE_CLASS a) => (a, Int) -> MutableByteArray -> IO ()
357+peek :: forall a. (NFData a, SERIALIZE_CLASS a) =>
358+ (a, Int) -> MutableByteArray -> IO ()
308359#ifdef USE_UNBOX
309−peek (val, _) arr = do
360+peek (_val, _) arr = do
310361 (val1 :: a) <- DESERIALIZE_OP 0 arr
311362#else
312−peek (val, n) arr = do
363+peek (_val, n) arr = do
313364 (_, val1 :: a) <- DESERIALIZE_OP 0 arr n
314365#endif
366+ -- If the datatype is not deeply strict or deepseq is not used then use
367+ -- Equality.
315368 -- Ensure that we are actually constructing the type and using it. This
316369 -- is important, otherwise the structure is created and discarded, the
317370 -- cost of creation of the structure is not accounted. Otherwise we may
@@ -319,35 +372,42 @@ peek (val, n) arr = do
319372 -- cost though. We could use deepseq but then we need to write
320373 -- instances of NFData and ensure that they are correct and perform
321374 -- well. Equality check also ensures correctness.
375+ {-
322376 if (val1 /= val)
323377 then error "peek: no match"
324378 else return ()
379+ -}
380+ val1 `deepseq` return ()
325381
326382{-# INLINE peekTimes #-}
327−peekTimes :: (Eq a, SERIALIZE_CLASS a) => Int -> a -> Int -> IO ()
383+peekTimes :: (NFData a, SERIALIZE_CLASS a) => Int -> a -> Int -> IO ()
328384peekTimes n val times = do
329385 arr <- newBytes n
330386 _ <- SERIALIZE_OP 0 arr val
331387 loopWith times peek (val, n) arr
332388
333389{-# INLINE trip #-}
334−trip :: forall a. (Eq a, SERIALIZE_CLASS a) => a -> IO ()
390+trip :: forall a. (NFData a, SERIALIZE_CLASS a) => a -> IO ()
335391trip val = do
336392 let n = getSize val
337393 arr <- newBytes n
338394 _ <- SERIALIZE_OP 0 arr val
339395#ifdef USE_UNBOX
340− val1 <- DESERIALIZE_OP 0 arr
396+ (val1 :: a) <- DESERIALIZE_OP 0 arr
341397#else
342− (_, val1) <- DESERIALIZE_OP 0 arr n
398+ (_, val1 :: a) <- DESERIALIZE_OP 0 arr n
343399#endif
344− -- Do not remove this, see the comments in peek.
400+ -- Do not remove this or use deepseq, see the comments in peek.
401+ {-
345402 if (val1 /= val)
346403 then error "roundtrip: no match"
347404 else return ()
405+ -}
406+ -- Note: deepseq is not needed if the datatype is strict
407+ val1 `deepseq` return ()
348408
349409{-# INLINE roundtrip #-}
350−roundtrip :: (Eq a, SERIALIZE_CLASS a) => a -> Int -> IO ()
410+roundtrip :: (NFData a, SERIALIZE_CLASS a) => a -> Int -> IO ()
351411roundtrip val times = loop times trip val
352412
353413-------------------------------------------------------------------------------
@@ -357,7 +417,8 @@ roundtrip val times = loop times trip val
357417{-# INLINE benchConst #-}
358418benchConst ::
359419 String
360− -> (forall a. (Eq a, SERIALIZE_CLASS a) => Int -> a -> Int -> IO ())
420+ -> (forall a. (NFData a, SERIALIZE_CLASS a) =>
421+ Int -> a -> Int -> IO ())
361422 -> Int
362423 -> Benchmark
363424benchConst gname f times =
@@ -385,7 +446,8 @@ benchConst gname f times =
385446{-# INLINE benchVar #-}
386447benchVar ::
387448 String
388− -> (forall a. (Eq a, SERIALIZE_CLASS a) => Int -> a -> Int -> IO ())
449+ -> (forall a. (NFData a, SERIALIZE_CLASS a) =>
450+ Int -> a -> Int -> IO ())
389451 -> BinTree Int
390452 -> [Int]
391453 -> Int