haskell - Unexpected memory growth with Control.Monad foldM -
i have following code, has been stripped down , think minimal possible has odd behaviour.
the code consists of 2 source files: 1 define data:
module myfunction data myfunction = myfunction { functionnumber :: int, functionresult :: io string } makemyfunction :: show => int -> io -> myfunction makemyfunction number result = myfunction { functionnumber = number, functionresult = result >>= return . show }
and other main:
module main (main) import system.cputime (getcputime) import data.list (foldl') import data.foldable (foldlm) import control.monad (foldm) import myfunction examplefunction = --let x = foldl' (\a b -> `seq` (a + b)) 0 [1..20000000] -- works --x <- foldlm (\a b -> `seq` return (a + b)) 0 [1..20000000] -- works (*) x <- foldm (\a b -> `seq` return (a + b)) 0 [1..20000000] -- doesn't print x return () runfunction fn = result <- functionresult fn duration <- getcputime if result /= "()" putstrln "" else return () putstrln (show (fromintegral duration / (10^9)) ++ "ms") return fn main = runfunction (makemyfunction 123 examplefunction) return ()
the code above (compiled using ghc 7.10.3 stack 1.0.0 default flags) has rapid increase in memory usage (exceeding 1gb), , takes typically 3.3 seconds.
if make changes code, example:
- use 1 of commented alternatives problem line
- take out line
runfunction
the memory usage remain minimal, , takes 1 second.
one feature think surprising me replacing foldm
foldlm
(which far know foldm = foldlm
) fixes problem.
also making changes code don't see has relationship problem lines of code fixes problem. example removing last putstrln.
another oddity if merge myfunction module main module, while doesn't fix problem, causes foldlm
behave foldm
using excessive memory.
in real code came from, have large number examplefunction
s, , there more main
code, , every encounter sort of unexplained memory usage functions, can resolved sort of voodoo.
i'm looking explanation behaviour. if know why occurs can avoiding it. compiler issue, or maybe misunderstanding on part?
(*) i've highlighted secondary issue causes same memory growth occur foldlm.
here foldlm
foldable.hs
(ghc)
-- | monadic fold on elements of structure, -- associating left, i.e. left right. foldlm :: (foldable t, monad m) => (b -> -> m b) -> b -> t -> m b foldlm f z0 xs = foldr f' return xs z0 f' x k z = f z x >>= k
and foldm
monad.hs
foldm :: (foldable t, monad m) => (b -> -> m b) -> b -> t -> m b {-# inlineable foldm #-} {-# specialise foldm :: (a -> b -> io a) -> -> [b] -> io #-} {-# specialise foldm :: (a -> b -> maybe a) -> -> [b] -> maybe #-} foldm = foldlm
i placed these definitions separate module test , tested execution , without inlineable / spesialise lines. whatever reason is, leaving out specialise directives helped , execution time , memory usage foldlm.
after little bit more digging, removing line
{-# specialise foldm :: (a -> b -> io a) -> -> [b] -> io #-}
effected most.
Comments
Post a Comment