Sla*_*kov 1 memory haskell lazy-evaluation ghc
此代码仅使用1Mb的RAM:
main = putStrLn $ show $ length (take 2000000 [1..])
Run Code Online (Sandbox Code Playgroud)
虽然此代码使用90Mb的RAM:
nums :: [Int]
nums = nextInts 0
where
nextInts x = x : nextInts (succ x)
main = putStrLn $ show $ length (take 2000000 nums)
Run Code Online (Sandbox Code Playgroud)
如果我这样改变它,它将再次使用1Mb的RAM:
nums :: [Int]
nums = nextInts 0
where
nextInts x
|x == 90000000 = [] -- some large number
|otherwise = x : nextInts (succ x)
main = putStrLn $ show $ length (take 2000000 nums)
Run Code Online (Sandbox Code Playgroud)
问题:有人可以解释为什么第二个代码示例将整个列表存储在RAM中,而第三个代码样本没有这样做.还描述了我应该如何更改第二个样本以使用O(1)RAM并且仍然是无限列表.
Eri*_*ikR 13
在第二种情况下,您的内存使用量不是来自存储列表,而是来自使用的未建立的thunk succ x.
succ是懒惰的,所以调用succ x只是在堆上分配一个新的thunk.这个thunk永远不会被评估,因为你永远不需要知道任何列表元素的值.
在第三种情况下,您正在x使用防护装置强制进行评估,x == 9000000因此没有建立起来.