私の目標: 要約しようとしている 1 GB の csv ファイルがあります。ファイルに「フィールド」/列 AM があるとします。特定のフィールドを別のフィールド (A など) で小計したいと思います。結果は、フィールド A の各値と、他の 3 つのフィールド (B、G、L など) の小計です。
問題: LINQ クエリでこれを処理しようとしていますが、メモリ不足の例外がスローされます。
これが私のクエリです:
Dim summarizedRecs = From line In System.IO.File.ReadLines(filepath)
Skip 1
Let e = New aRecord(line)
Group e
By e.A
Into g = Group
Select summarizedR = New With {
A,
.TotalB = g.Sum(Function(x) x.B),
.TotalG = g.Sum(Function(x) x.G),
.TotalL = g.Sum(Function(x) x.L)}
Order By summarizedR.A
aRecord
コンストラクターがテキスト行を受け取り、その行を適切なフィールドに解析する単純なクラスです。それはうまくいきます。
このアプローチは、100 MB までの小さなファイルでうまく機能します。アプリケーションが使用するメモリは、100 MB ファイルと 1 GB ファイルの実行時に増加します。
LINQ グループはここで必要なものではないと思いますが、別の LINQ アプローチについてはわかりません。ありますか?
LINQ は e のすべてのインスタンスをグループに保持していると思います。最後に、e のグループは必要ありません。各 e のフィールドが適切なグループに追加された後、その e を破棄できます。e のグループから得られた結果の小計が欲しいだけです。
また、LINQ をすべてスキップし、Dictionary(Of T1, T2) を使用してこれを正常に実装しました。そうすることで、テキストの各行を読み取り、aRecord のインスタンスを作成し、その合計を Dictionary 内の適切なキーと値のペアに適用します。このアプローチでは、aRecord のインスタンスは 1 つだけです。これはメモリに関して効率的です。消費されるメモリは横ばいになり、比較的低く抑えられます。
したがって、Dictionary アプローチは 1 GB のファイルで機能します。しかし、LINQの代替手段はありますか?