6

我有一个代码:

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,仅根据需要计算单个序列元素?

4

2 回答 2

8
seq {for i in [1 .. 100000000] -> i} |> Seq.take 100000

创建一个序列,该序列将根据您的要求从 list 生成项目[1 .. 100000000]。这要求列表在内存中。该列表对于 32 位内存来说太大了,因此OutOfMemoryException. 你应该试试

seq {for i in 1 .. 100000000 -> i} |> Seq.take 100000
于 2013-08-20T12:47:17.790 回答
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; ...]

它启动了原始庞大列表的内存实例化。

于 2013-08-20T13:39:10.530 回答