2

Seq モジュールにいくつかの集計関数を追加しようとしています。ここにリストされている関数のいくつかの実装を見ていました。

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

免責事項の 1 つは、「この関数は、シーケンスが繰り返されるとすぐに最初のシーケンス全体を消化するシーケンスを返します。結果として、この関数は大規模または無限のシーケンスで使用しないでください。」これは、GroupBy などの多くの関数に当てはまります。

  • 最初の質問: 大きなシーケンスを効率的に処理できる集約関数を作成する方法はありますか? 「大」が主観的であることはわかっています。そのような関数を書くための一般的なパターンを探しています。

  • 2 番目の質問: Dictionary などのコレクション (集約関数内で定義されているもの) が効率的にガベージ コレクションされるようにするにはどうすればよいですか? 範囲外になったときに辞書を収集する必要があることは理解していますが、それを明示的に示す方法はありますか? 辞書が関数内にとどまるようにスコープされていることを考えると、そのどちらでも .Clear() を呼び出すことはできませんか?

4

1 に答える 1

6

最初の質問に答えるには - この場合、大きな入力の問題は、関数が結果を出す前にシーケンス全体を処理するfold必要があることです。groupByあなたができることがいくつかあります:

  • Seq.scan値を集約するような関数を使用しますfoldが、すべての要素を追加した後に現在の状態を生成します-結果もシーケンスであり、それを遅延して消費できます(たとえば、より正確な結果を得ることができます)。

  • を返す関数を作成するときseq<'a>は、シーケンスから次の要素を取得するときに、入力の予測可能な数の要素のみを消費するように設計する必要があります (ただし、入力シーケンス全体ではありません)。これはたとえば では不可能groupByですが、同じグループの隣接する要素のみをグループ化するグループ化のような構造を書くことができます。

2 番目の質問に答えると、通常、ガベージ コレクターについてあまり心配する必要はありません。関数の最後でガベージ コレクションを強制すると、GC が正常に機能することに頼るよりも、おそらくより多くの害が生じるでしょう。

于 2011-06-23T11:35:41.653 に答える