@@ -17,7 +17,7 @@ module Main (main) where
18-------------------------------------------------------------------------------
18-------------------------------------------------------------------------------
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)
73+instance NFData Unit where
@@ -81,6 +85,10 @@ instance SERIALIZE_CLASS Sum2
81$(DERIVE_CLASS ''Sum2)
85$(DERIVE_CLASS ''Sum2)
88+instance NFData Sum2 where
@@ -115,6 +123,10 @@ instance SERIALIZE_CLASS Sum25
115$(DERIVE_CLASS ''Sum25)
123$(DERIVE_CLASS ''Sum25)
126+instance NFData Sum25 where
118data Product25
130data Product25
119 = Product25
131 = Product25
@@ -150,6 +162,37 @@ instance SERIALIZE_CLASS Product25
150$(DERIVE_CLASS ''Product25)
162$(DERIVE_CLASS ''Product25)
165+instance NFData Product25 where
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)
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)
244+instance NFData CustomDT1 where
247+ rnf (CDT1C2 i) = i `seq` ()
248+ rnf (CDT1C3 i1 i2) = i1 `seq` i2 `seq` ()
201-------------------------------------------------------------------------------
250-------------------------------------------------------------------------------
202-- Recursive ADT
251-- Recursive ADT
203-------------------------------------------------------------------------------
252-------------------------------------------------------------------------------
@@ -215,6 +264,7 @@ $(deriveSerialize ''BinTree)
217instance NFData a => NFData (BinTree a) where
266instance NFData a => NFData (BinTree a) where
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` ()
@@ -304,14 +354,17 @@ pokeTimes val times = do
304 loopWith times poke arr val
354 loopWith times poke arr val
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
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
366+ -- If the datatype is not deeply strict or deepseq is not used then use
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.
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 ()
380+ val1 `deepseq` return ()
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
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
342− (_, val1) <- DESERIALIZE_OP 0 arr n
398+ (_, val1 :: a) <- DESERIALIZE_OP 0 arr n
344− -- Do not remove this, see the comments in peek.
400+ -- Do not remove this or use deepseq, see the comments in peek.
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 ()
406+ -- Note: deepseq is not needed if the datatype is strict
407+ val1 `deepseq` return ()
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
353-------------------------------------------------------------------------------
413-------------------------------------------------------------------------------
@@ -357,7 +417,8 @@ roundtrip val times = loop times trip val
357{-# INLINE benchConst #-}
417{-# INLINE benchConst #-}
358benchConst ::
418benchConst ::
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 ())
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 ::
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