Ответ 1
Теперь я нахожусь на работе, поэтому я смотрю несколько более новые бит, чем Beta1, но на моем ящике в режиме Release, а затем глядя на скомпилированный код с .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 при компиляции в режиме "Release". И они работают примерно с такой же скоростью, как этот код С#:
public class CSharpExample
{
public static IEnumerable<int> StartFrom(int x)
{
while (true)
{
yield return x;
x++;
}
}
}
(например, я запустил все три версии в своем ящике и напечатал миллионный результат, и каждая версия заняла около 1,3, +/- 1). (Я не делал никакого профилирования памяти, возможно, я пропустил что-то важное.)
Короче говоря, я бы не стал слишком много думать о таких проблемах, если вы не измеряете и не видите проблему.
ИЗМЕНИТЬ
Я понимаю, что я действительно не ответил на вопрос... Я думаю, что короткий ответ: "Нет, он не течет". (Существует особый смысл, в котором все "бесконечные" IEnumerables (с кэшированным хранилищем) "утечка" (в зависимости от того, как вы определяете "утечку" ), см.
Избегайте (с бесконечными последовательностями последовательности F #)
для интересного обсуждения IEnumerable (aka 'seq') по сравнению с LazyList и того, как потребитель может охотно потреблять LazyLists, чтобы "забыть" старые результаты, чтобы предотвратить определенную "утечку".)