leancheck-0.9.2: bench/memory-usage.hs
-- memory-usage.hs -- example program illustrating a limitation of LeanCheck
--
-- Copyright (c) 2020 Rudy Matela.
-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
--
-- Many thanks to Jonas Duregard for providing this example.
--
-- If we set the test limit to millions of values, memory consumption may be
-- too high. This is aggravated depending on how tests are ordered.
--
-- See below.
import Test.LeanCheck
import Data.Int
import Data.Word
-- dummy property that is always 'True' for a correct 'Num' instance.
evenOrOdd :: (Listable a, Show a, Integral a) => [a] -> Bool
evenOrOdd xs = all (\x -> odd x || even x) xs
main :: IO ()
main = do
-- With just the following 10 lines
-- this program consumes around 500 Mb of memory.
-- At the end of each checkFor call
-- the underlying tiers/list is garbage collected.
checkFor 1000000 (evenOrOdd :: [Int] -> Bool)
checkFor 1000000 (evenOrOdd :: [Int8] -> Bool)
checkFor 1000000 (evenOrOdd :: [Int16] -> Bool)
checkFor 1000000 (evenOrOdd :: [Int32] -> Bool)
checkFor 1000000 (evenOrOdd :: [Int64] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word8] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word16] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word32] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word64] -> Bool)
-- However, if the following 10 lines are uncommented
-- we increase memory consumption.
-- Turns out the GC will not trigger as Haskell sees it will still use
-- enumerated values, so it tries to keep values in memory.
-- The maximum resident set size will increase to 3 000 Mb.
{-
checkFor 1000000 (evenOrOdd :: [Int] -> Bool)
checkFor 1000000 (evenOrOdd :: [Int8] -> Bool)
checkFor 1000000 (evenOrOdd :: [Int16] -> Bool)
checkFor 1000000 (evenOrOdd :: [Int32] -> Bool)
checkFor 1000000 (evenOrOdd :: [Int64] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word8] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word16] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word32] -> Bool)
checkFor 1000000 (evenOrOdd :: [Word64] -> Bool)
-}
-- This is a limitation of LeanCheck
-- that comes from using simple lists of lists
-- as the means for enumeration.