senganb@ia.nsc.com (Sengan Baring-Gould) wrote:
mapM seems to be a memory hog (and thus also concatMapM). In the following eg:
main = mapM print ([1..102400] :: [Integer])
memory usage climbs to 1.6M with ghc and needs -K20M
As a guess: since 'mapM print ([1..102400] :: [Integer])' has type 'IO [()]', perhaps the result of the IO operation -- a list of 100K empty tuples -- is the culprit, even though the result is never used.
Does 'mapM_ print ... ' (:: IO ()) perform any better?
Yes, but in the following eg
main = print $ sum x x = _scc_ "x" [1..102400] :: [Integer]
x takes 1M allocations, and I would think that () would be smaller than an Integer. Therefore I'm not sure that is the reason. The sum is there to force the evaluation.
Assuming you are right, why do I see the same 1.6M profile with:
main = mapM2 (_scc_ "p" (\x -> print x)) ([1..102400] :: [Integer]) >> return ()
mapM2 :: Monad m => (a -> m b) -> [a] -> m [b] mapM2 f [] = return [] mapM2 f (c:cs) = _scc_ "a" (>>=) (_scc_ "d" f c) (\x -> _scc_ "b" (>>=) (_scc_ "e" mapM2 f cs) (\xs -> _scc_ "f" return (x:xs)))
Is >>= not lazy? Sengan