我现在正在工作,所以我正在查看比 Beta1 稍新的位,但是在我的盒子上处于发布模式,然后使用 .Net Reflector 查看编译的代码,看来这两个
let rec startFromA x =
seq {
yield x
yield! startFromA (x + 1)
}
let startFromB x =
let z = ref x
seq {
while true do
yield !z
incr z
}
在“发布”模式下编译时生成几乎相同的 MSIL 代码。它们的运行速度与以下 C# 代码大致相同:
public class CSharpExample
{
public static IEnumerable<int> StartFrom(int x)
{
while (true)
{
yield return x;
x++;
}
}
}
(例如,我在我的盒子上运行了所有三个版本并打印了第 100 万个结果,每个版本大约需要 1.3 秒,+/- 1 秒)。(我没有做任何内存分析;我可能遗漏了一些重要的东西。)
简而言之,除非您衡量并看到问题,否则我不会过多思考此类问题。
编辑
我意识到我并没有真正回答这个问题......我认为简短的回答是“不,它不会泄漏”。(有一种特殊意义,即所有“无限”IEnumerables(带有缓存的后备存储)“泄漏”(取决于您如何定义“泄漏”),请参阅
避免堆栈溢出(使用 F# 无限序列)
有关 IEnumerable(又名“seq”)与 LazyList 的有趣讨论,以及消费者如何急切地使用 LazyLists 以“忘记”旧结果以防止某种“泄漏”。)