记忆在ghci中严格求和/严格foldl [英] Memory blowing up for strict sum/strict foldl in ghci

查看:87
本文介绍了记忆在ghci中严格求和/严格foldl的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

正如为什么(sum $ takeWhile (< 10000000)[1 ..])使用如此多的内存?以下内容不是 ghci 中的内存:

  foldl'(+)0 $ takeWhile(<10000000)[1 ..] 
pre>

但是,如果我创建一个包含以下内容的文件:

  import Data .List 

longList :: [Int]
longList = [1 ..]

结果:: Int
result = foldl'(+) 0 $ takeWhile(< 10000000)longList

main = do
print $ result

并加载到ghci中,然后在运行该程序时内存消耗就会爆炸。为什么是这样,我能做些什么来修复这个程序?我使用ghc 7.8.3。





似乎炸毁提供我首先通过 ghc Test.hs 编译。但是,如果我删除了所有 .hi .o 文件,并通过加载到ghci中, ghci Test.hs 然后内存确实炸毁。

解决方案

我相信这是由于GHCi中的文件与标识符 longList 的不同处理方式与<编译时的:l 不同。 / p>

当GHCi中的:l ModuleName 时,默认情况下所有 顶级标识符该模块进入范围,以便您可以高效地进行调试。举例来说,这包括 longList 。这意味着GHCi 在评估后保留 longList 的内容,这会导致内存泄漏。我怀疑是这种情况,即使使用 -fobjectcode ,所以我不确定其他评论中讨论的行为实际上是否是一个bug。



相反,当你编译模块时,GHC使用模块导出列表来找出结果中暴露的标识符。由于您没有明确的模块声明,因此它默认为(

 模块Main(main)其中

这意味着编译时,GHC可以注意到除 main 之外的所有标识符都没有公开,并且 longList 只能使用一次。然后它可以保持其价值,避免内存泄漏。


As mentioned in Why does (sum $ takeWhile (<10000000) [1..]) use so much memory? the following does not blow up the memory in ghci :

foldl' (+) 0 $ takeWhile (< 10000000) [1 .. ]

However if I create a file containing :

import Data.List

longList::[Int]
longList = [1 .. ]

result :: Int
result = foldl' (+) 0 $ takeWhile (< 10000000) longList

main = do
  print $ result

and load into ghci, then upon running the program the memory consumption blows up. Why is this, and what can I do to fix the program? I am using ghc 7.8.3.

[EDIT]

It does not seem to blow up provided I compile first via ghc Test.hs. But if I remove all the .hi and .o files, and load into ghci via ghci Test.hs then the memory does blow up.

解决方案

I believe this is due to the different treatment of the identifier longList when you :l the file in GHCi, as opposed to when it is compiled.

When you :l ModuleName in GHCi, by default all top-level identifiers in the module come into scope, so that you may debug it efficiently. For your example, this includes longList. This means that GHCi keeps around the content of longList after it has been evaluated, which gives a memory leak. I suspect this is the case even with -fobjectcode, so I am not sure the behavior discussed in the other comments actually is a bug.

When on the contrary you compile the module, GHC uses the module export list to find out which identifiers are exposed in the result. Since you have no explicit module declaration, it defaults to (last paragraph)

module Main (main) where

This means that when compiling, GHC can note that all identifiers except main are not exposed, and that longList is only used once. It can then drop keeping its value around, avoiding the memory leak.

这篇关于记忆在ghci中严格求和/严格foldl的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆