次のように公開するこのクラスがありIEnumerable<Record>
ます(実装の詳細は省略されています):
public class SomeFileReader() {
public IEnumerable<Record> Records()
{
using (StreamReader sr = new StreamReader(this.Path, this.Encoding, true))
{
var hdr = this.HeaderParser.Parse(sr.ReadLine()); //Parse, but further ignore header (the HeaderParser might throw though)
while (!sr.EndOfStream)
yield return this.RecordParser.Parse(sr.ReadLine()) as Record;
}
}
ARecord
には、他の多くのプロパティ(したがって、「メモリ/ストレージに関して」非常に大きい)の中で、Id
プロパティ(Key
2つの「部分」で構成されるオブジェクト)があります。完全を期すために、これは次のようになります。
public class Key : IEquatable<Key>
{
public string OperatorCode { get; set; }
public string Key { get; set; }
public bool Equals(Key other)
{
return (this.OperatorCode.Equals(other.OperatorCode, StringComparison.OrdinalIgnoreCase))
&& (this.Key.Equals(other.Key, StringComparison.OrdinalIgnoreCase));
}
}
ファイルには「キー順」のレコードが含まれているため、レコードのID
オンディスクによってソートされます (保証されます)。
メモリ内には、HashSet<Key>
から処理したい の レコードもありSomeFileReader
ます。現在、私のテストファイルは数メガバイトしかありませんが、近い将来これが非常に大きくなると予測しています。現時点ではDictionary<Key, Record>
、「処理される」レコードの「リスト」から処理したい特定のレコードを簡単かつ迅速に取得するために、ファイル全体をメモリに読み込むだけです。これは次のようになります。
var recordsfromfile = MyFileImporter.Records().ToDictionary(k => k.Key.Key);
もちろん、ファイルが(あまりにも)大きくなると、これは問題になります。
しかし、私は考えていたを公開しているので...レコードはキー順であるため、ファイルを完全IEnumerable<Record>
にメモリに読み込む必要はありません。処理するキーの「リスト」を含む単純なIntersect()で十分です。はすでに実装されており、実装がまったく難しくない が必要な場合があります。しかし、私は(私が思うに)脱線します..Key
IEquatable
IEQualityComparer<Key>
Intersect()
ドキュメントには次のように記載されています。
このメソッドによって返されたオブジェクトが列挙されると、 Intersect は を列挙し、
first
そのシーケンスのすべての個別の要素を収集します。次に、 を列挙second
し、両方のシーケンスで発生する要素をマークします。最後に、マークされた要素が収集された順序で生成されます。
(私のものを強調)
したがって、私が正しく理解していればfirst
、IEnumerable<Record>
ファイルはまだ完全にメモリに読み込まれます。そして、それがsecond
すべて私の「処理対象」の「リスト」と一致したとしても、依然として非常に大量のデータである可能性があるメモリに読み込まれます。または、ドキュメントを読み違えていますか?これは「最終的に」つまずいたり、ドキュメントを誤解していますか?
私が防ぎたいのは、明らかに、
- a) データの一部を 1 つずつ処理するという唯一の目的で大量のデータをメモリに読み込まないこと)
- b)「処理対象」の「リスト」の各レコードに対して同じファイルを何度も(再)開かない(したがって、イテレータをリセットしないように注意したい)
簡単に言えば。私がIntersect()
やりたいことをしますか?別の方法を使用する必要がありますか? ネストされた for ループ? これを効率的に処理する方法に関する他のアイデアはありますか?
編集:「処理されるキーのリスト」が実際にはHashSet<Key>
.
Ps私はベッドでこの目的のためにLinqを使用することについて脳波に襲われたばかりで、これを理解する前に眠ることができません. 残念ながら、私は休暇中で、まともな Visual Studio インスタンスから何マイルも離れているので、これをテストするだけです。それは私の退役後まで待たなければならないでしょう(だからミスは言っています...それについては見ていきます...)