我有一个代码:
seq {for i in [1 .. 100000000] -> i} |> Seq.take 100000;;
Real: 00:00:00.000, CPU: 00:00:00.000, GC gen0: 0, gen1: 0, gen2: 0
val it : seq<int> =
Error: Exception of type 'System.OutOfMemoryException' was thrown.
此代码导致内存不足。为什么?为什么在计算时间后(操作完成后)会抛出异常? AFAIK,个别序列元素仅在需要时计算?
答案 0 :(得分:8)
seq {for i in [1 .. 100000000] -> i} |> Seq.take 100000
从列表[1 .. 100000000]
创建一个将根据您的要求生成项目的序列。这要求列表在内存中。该列表对于32位内存来说太大了,因此OutOfMemoryException
。你应该试试
seq {for i in 1 .. 100000000 -> i} |> Seq.take 100000
答案 1 :(得分:6)
除了揭示核心问题的原因之外,可能有必要解决问题的第二部分,即为什么在操作完成后抛出异常。
为了理解这一点,这将有助于考虑
let mySeq = seq {for i in [1 .. 100000000] -> i} |> Seq.take 100000;;
不会出现任何例外情况,而看似无害
seq {for i in [1 .. 100000000] -> i};;
之后会出现与原版相同的异常,尽管我们似乎无论如何都不会尝试实现序列。
没错,我们没有,但是 FSI确实,试图打印出几个第一序列成员的值,比如下面的一个较小的列表:
seq {for i in [1 .. 100] -> i};;
val it : seq<int> = seq [1; 2; 3; 4; ...]
启动原始庞大列表的内存实例化。