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 examplefunctions, , 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

Popular posts from this blog

get url and add instance to a model with prefilled foreign key :django admin -

css - Make div keyboard-scrollable in jQuery Mobile? -

ruby on rails - Seeing duplicate requests handled with Unicorn -