When is memoization automatic in GHC Haskell? -
i can't figure out why m1 apparently memoized while m2 not in following:
m1 = ((filter odd [1..]) !!) m2 n = ((filter odd [1..]) !! n)
m1 10000000 takes 1.5 seconds on first call, , fraction of on subsequent calls (presumably caches list), whereas m2 10000000 takes same amount of time (rebuilding list each call). idea what's going on? there rules of thumb if , when ghc memoize function? thanks.
ghc not memoize functions.
it does, however, compute given expression in code @ once per time surrounding lambda-expression entered, or @ once ever if @ top level. determining lambda-expressions can little tricky when use syntactic sugar in example, let's convert these equivalent desugared syntax:
m1' = (!!) (filter odd [1..]) -- nb: see below! m2' = \n -> (!!) (filter odd [1..]) n
(note: haskell 98 report describes left operator section (a %)
equivalent \b -> (%) b
, ghc desugars (%) a
. these technically different because can distinguished seq
. think might have submitted ghc trac ticket this.)
given this, can see in m1'
, expression filter odd [1..]
not contained in lambda-expression, computed once per run of program, while in m2'
, filter odd [1..]
computed each time lambda-expression entered, i.e., on each call of m2'
. explains difference in timing seeing.
actually, versions of ghc, optimization options, share more values above description indicates. can problematic in situations. example, consider function
f = \x -> let y = [1..30000000] in foldl' (+) 0 (y ++ [x])
ghc might notice y
not depend on x
, rewrite function to
f = let y = [1..30000000] in \x -> foldl' (+) 0 (y ++ [x])
in case, new version less efficient because have read 1 gb memory y
stored, while original version run in constant space , fit in processor's cache. in fact, under ghc 6.12.1, function f
twice fast when compiled without optimizations compiled -o2
.
Comments
Post a Comment