Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 为什么这个程序会占用这么多内存?_Haskell_Memory_Lazy Evaluation_Space Complexity - Fatal编程技术网

Haskell 为什么这个程序会占用这么多内存?

Haskell 为什么这个程序会占用这么多内存?,haskell,memory,lazy-evaluation,space-complexity,Haskell,Memory,Lazy Evaluation,Space Complexity,不久前,在哈斯克尔,我需要使用一种算法来解决一个KP问题 下面是我的代码的样子: stepKP::[Int]->(Int,Int)->[Int] 步骤kp l(p,v)=使用最佳选项l(下降p l)选择p l++zip 其中,选项a=最大值(a+v) kp::[(Int,Int)]->Int->Int kp l pMax=last$foldl stepKP[0 | i我们可以将左折叠视为执行迭代,同时保留最后返回的累加器 当有大量迭代时,一个问题是累加器可能在内存中变得太大。由于Haskell很

不久前,在哈斯克尔,我需要使用一种算法来解决一个KP问题

下面是我的代码的样子:

stepKP::[Int]->(Int,Int)->[Int]
步骤kp l(p,v)=使用最佳选项l(下降p l)选择p l++zip
其中,选项a=最大值(a+v)
kp::[(Int,Int)]->Int->Int

kp l pMax=last$foldl stepKP[0 | i我们可以将左折叠视为执行迭代,同时保留最后返回的累加器

当有大量迭代时,一个问题是累加器可能在内存中变得太大。由于Haskell很懒惰,即使累加器是原始类型,如
Int
:在一些看似无辜的
Int
值后面,可能潜伏着大量以thunk形式的挂起操作

这里,严格的左折叠函数
foldl'
非常有用,因为它确保在计算左折叠时,累加器始终保持在(WHNF)中

唉,有时候这还不够。WHNF只说求值已上升到值的“最外层构造函数”。这对于
Int
,已经足够了,但是对于列表或树之类的递归类型,这并不能说明什么:Thunk可能只是潜伏在列表的更下面,或者在下面的分支中

这里就是这种情况,累加器是一个在每次迭代时重新创建的列表。每次迭代,
foldl'
只对列表进行求值,直到
:\u
。未求值的
max
zipWith
操作开始堆积

我们需要的是一种在每次迭代时触发对累加器列表的完整计算的方法,它可以清除内存中的任何
max
zipWith
thunks。这就是我们要完成的。当
force$something
被计算到WHNF时,
something
被完全计算到,也就是说,不仅仅是到outermost构造函数,但“深度”


请注意,我们仍然需要
foldl'
,以便在每次迭代时“触发”
强制

foldl
->
foldl'
?我确实尝试过,但这没有什么区别……另一个快速尝试的方法是启用优化进行编译。@rambi将使用
[10000999..8000]
而不是
reverse[8000..10000]
。reverse总是需要具体化整个列表。而且
splitAt
会比单独使用
take
drop
好,甚至更糟!顺便说一句,对我来说,只使用武力而不使用foldl就足够了。。。
1980100
   9,461,474,416 bytes allocated in the heap
   6,103,730,184 bytes copied during GC
   1,190,494,880 bytes maximum residency (18 sample(s))
       5,098,848 bytes maximum slop
            2624 MiB total memory in use (0 MB lost due to fragmentation)

                                     Tot time (elapsed)  Avg pause  Max pause
  Gen  0      6473 colls,     0 par    2.173s   2.176s     0.0003s    0.0010s
  Gen  1        18 colls,     0 par    4.185s   4.188s     0.2327s    1.4993s

  INIT    time    0.000s  (  0.000s elapsed)
  MUT     time    3.320s  (  3.322s elapsed)
  GC      time    6.358s  (  6.365s elapsed)
  EXIT    time    0.000s  (  0.000s elapsed)
  Total   time    9.679s  (  9.687s elapsed)

  %GC     time       0.0%  (0.0% elapsed)

  Alloc rate    2,849,443,762 bytes per MUT second

  Productivity  34.3% of total user, 34.3% of total elapsed