Seq模块中的聚合函数

时间:2011-06-23 03:36:45

标签: f# dictionary seq

我正在尝试向Seq模块添加一些额外的聚合函数。我正在研究这里列出的一些功能的实现:

https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/seq.fs

其中一个免责声明是“该函数返回一个序列,一旦该序列被迭代,就会消化整个初始序列。因此,该函数不应该用于大序列或无限序列。” 许多功能都是如此,例如GroupBy。

  • 第一个问题:是否有方法可以编写可以有效处理大型序列的聚合函数?我知道“大”是主观的;我只是在寻找编写这些函数的一般模式。

  • 第二个问题:我如何确保像Dictionary这样的集合(在集合函数中定义)被有效地垃圾收集?我理解字典应该在它们超出范围时收集,但有没有办法明确指出?鉴于字典的范围是保留在函数内,我不能在那上面调用.Clear()吗?

1 个答案:

答案 0 :(得分:6)

回答你的第一个问题 - 在这种情况下,输入的问题是必须在foldgroupBy之类的函数给出之前处理整个序列结果。你可以做一些事情:

  • 使用像Seq.scan这样的函数来聚合像fold这样的值但在添加每个元素后产生当前状态 - 结果也是序列,你可以懒得消耗它(并且越来越多)确切的结果,例如)。

  • 当编写返回seq<'a>的函数时,您应该设计它们,以便从序列中获取下一个元素只会消耗一些可预测数量的输入元素(但不会占用整个输入序列)。这是不可能的,例如对于groupBy,但您可以编写类似分组的构造,仅对同一组的相邻元素进行分组。

要回答第二个问题 - 您通常不应该过多担心垃圾收集器。在功能结束时强制进行垃圾收集可能会造成更多伤害,而不仅仅是依靠GC才能正常工作。