on master help sign in
Use deepseq instead of equality check
282d79cHarendra Kumar
benchmark/Streamly/Benchmark/Data/Serialize.hs+74−12
@@ -17,7 +17,7 @@ module Main (main) where
17-- Imports
17-- Imports
18-------------------------------------------------------------------------------
18-------------------------------------------------------------------------------
19
19
20−import Control.DeepSeq (NFData(..))
20+import Control.DeepSeq (NFData(..), deepseq)
21import GHC.Generics (Generic)
21import GHC.Generics (Generic)
22import System.Random (randomRIO)
22import System.Random (randomRIO)
23#ifndef USE_UNBOX
23#ifndef USE_UNBOX
@@ -70,6 +70,10 @@ instance SERIALIZE_CLASS Unit
70$(DERIVE_CLASS ''Unit)
70$(DERIVE_CLASS ''Unit)
71#endif
71#endif
72
72
73+instance NFData Unit where
74+ {-# INLINE rnf #-}
75+ rnf _ = ()
76+
73data Sum2
77data Sum2
74 = Sum21
78 = Sum21
75 | Sum22
79 | Sum22
@@ -81,6 +85,10 @@ instance SERIALIZE_CLASS Sum2
81$(DERIVE_CLASS ''Sum2)
85$(DERIVE_CLASS ''Sum2)
82#endif
86#endif
83
87
88+instance NFData Sum2 where
89+ {-# INLINE rnf #-}
90+ rnf _ = ()
91+
84data Sum25
92data Sum25
85 = Sum251
93 = Sum251
86 | Sum252
94 | Sum252
@@ -115,6 +123,10 @@ instance SERIALIZE_CLASS Sum25
115$(DERIVE_CLASS ''Sum25)
123$(DERIVE_CLASS ''Sum25)
116#endif
124#endif
117
125
126+instance NFData Sum25 where
127+ {-# INLINE rnf #-}
128+ rnf _ = ()
129+
118data Product25
130data Product25
119 = Product25
131 = Product25
120 Int
132 Int
@@ -150,6 +162,37 @@ instance SERIALIZE_CLASS Product25
150$(DERIVE_CLASS ''Product25)
162$(DERIVE_CLASS ''Product25)
151#endif
163#endif
152
164
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+
153-- XXX derived Eq instance is not inlined
196-- XXX derived Eq instance is not inlined
154instance Eq Product25 where
197instance Eq Product25 where
155 {-# INLINE (==) #-}
198 {-# INLINE (==) #-}
@@ -198,6 +241,12 @@ instance SERIALIZE_CLASS CustomDT1
198$(DERIVE_CLASS ''CustomDT1)
241$(DERIVE_CLASS ''CustomDT1)
199#endif
242#endif
200
243
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+
201-------------------------------------------------------------------------------
250-------------------------------------------------------------------------------
202-- Recursive ADT
251-- Recursive ADT
203-------------------------------------------------------------------------------
252-------------------------------------------------------------------------------
@@ -215,6 +264,7 @@ $(deriveSerialize ''BinTree)
215#endif
264#endif
216
265
217instance NFData a => NFData (BinTree a) where
266instance NFData a => NFData (BinTree a) where
267+ {-# INLINE rnf #-}
218 rnf (Leaf a) = rnf a `seq` ()
268 rnf (Leaf a) = rnf a `seq` ()
219 rnf (Tree l r) = rnf l `seq` rnf r `seq` ()
269 rnf (Tree l r) = rnf l `seq` rnf r `seq` ()
220
270
@@ -304,14 +354,17 @@ pokeTimes val times = do
304 loopWith times poke arr val
354 loopWith times poke arr val
305
355
306{-# INLINE peek #-}
356{-# 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 ()
308#ifdef USE_UNBOX
359#ifdef USE_UNBOX
309−peek (val, _) arr = do
360+peek (_val, _) arr = do
310 (val1 :: a) <- DESERIALIZE_OP 0 arr
361 (val1 :: a) <- DESERIALIZE_OP 0 arr
311#else
362#else
312−peek (val, n) arr = do
363+peek (_val, n) arr = do
313 (_, val1 :: a) <- DESERIALIZE_OP 0 arr n
364 (_, val1 :: a) <- DESERIALIZE_OP 0 arr n
314#endif
365#endif
366+ -- If the datatype is not deeply strict or deepseq is not used then use
367+ -- Equality.
315 -- Ensure that we are actually constructing the type and using it. This
368 -- Ensure that we are actually constructing the type and using it. This
316 -- is important, otherwise the structure is created and discarded, the
369 -- is important, otherwise the structure is created and discarded, the
317 -- cost of creation of the structure is not accounted. Otherwise we may
370 -- cost of creation of the structure is not accounted. Otherwise we may
@@ -319,35 +372,42 @@ peek (val, n) arr = do
319 -- cost though. We could use deepseq but then we need to write
372 -- cost though. We could use deepseq but then we need to write
320 -- instances of NFData and ensure that they are correct and perform
373 -- instances of NFData and ensure that they are correct and perform
321 -- well. Equality check also ensures correctness.
374 -- well. Equality check also ensures correctness.
375+ {-
322 if (val1 /= val)
376 if (val1 /= val)
323 then error "peek: no match"
377 then error "peek: no match"
324 else return ()
378 else return ()
379+ -}
380+ val1 `deepseq` return ()
325
381
326{-# INLINE peekTimes #-}
382{-# INLINE peekTimes #-}
327−peekTimes :: (Eq a, SERIALIZE_CLASS a) => Int -> a -> Int -> IO ()
383+peekTimes :: (NFData a, SERIALIZE_CLASS a) => Int -> a -> Int -> IO ()
328peekTimes n val times = do
384peekTimes n val times = do
329 arr <- newBytes n
385 arr <- newBytes n
330 _ <- SERIALIZE_OP 0 arr val
386 _ <- SERIALIZE_OP 0 arr val
331 loopWith times peek (val, n) arr
387 loopWith times peek (val, n) arr
332
388
333{-# INLINE trip #-}
389{-# INLINE trip #-}
334−trip :: forall a. (Eq a, SERIALIZE_CLASS a) => a -> IO ()
390+trip :: forall a. (NFData a, SERIALIZE_CLASS a) => a -> IO ()
335trip val = do
391trip val = do
336 let n = getSize val
392 let n = getSize val
337 arr <- newBytes n
393 arr <- newBytes n
338 _ <- SERIALIZE_OP 0 arr val
394 _ <- SERIALIZE_OP 0 arr val
339#ifdef USE_UNBOX
395#ifdef USE_UNBOX
340− val1 <- DESERIALIZE_OP 0 arr
396+ (val1 :: a) <- DESERIALIZE_OP 0 arr
341#else
397#else
342− (_, val1) <- DESERIALIZE_OP 0 arr n
398+ (_, val1 :: a) <- DESERIALIZE_OP 0 arr n
343#endif
399#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+ {-
345 if (val1 /= val)
402 if (val1 /= val)
346 then error "roundtrip: no match"
403 then error "roundtrip: no match"
347 else return ()
404 else return ()
405+ -}
406+ -- Note: deepseq is not needed if the datatype is strict
407+ val1 `deepseq` return ()
348
408
349{-# INLINE roundtrip #-}
409{-# INLINE roundtrip #-}
350−roundtrip :: (Eq a, SERIALIZE_CLASS a) => a -> Int -> IO ()
410+roundtrip :: (NFData a, SERIALIZE_CLASS a) => a -> Int -> IO ()
351roundtrip val times = loop times trip val
411roundtrip val times = loop times trip val
352
412
353-------------------------------------------------------------------------------
413-------------------------------------------------------------------------------
@@ -357,7 +417,8 @@ roundtrip val times = loop times trip val
357{-# INLINE benchConst #-}
417{-# INLINE benchConst #-}
358benchConst ::
418benchConst ::
359 String
419 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 ())
361 -> Int
422 -> Int
362 -> Benchmark
423 -> Benchmark
363benchConst gname f times =
424benchConst gname f times =
@@ -385,7 +446,8 @@ benchConst gname f times =
385{-# INLINE benchVar #-}
446{-# INLINE benchVar #-}
386benchVar ::
447benchVar ::
387 String
448 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 ())
389 -> BinTree Int
451 -> BinTree Int
390 -> [Int]
452 -> [Int]
391 -> Int
453 -> Int