これは、現在直面している問題など、問題の説明がないと答えるのが少し難しいですが、以下は、同様のシナリオでの最近の経験に基づいたいくつかの考えです. ただし、このタイプのモデルに変更するのは大変な作業です。そのため、それを「修正」するためにどれだけ投資できるかにもよります。「あなたの問題」が「私たちの問題」と同じであるとは約束できません。問題」、私の言いたいことがわかるなら。したがって、次のアプローチがうまくいかない場合でも、クロスしないでください。
それだけの量のデータをメモリにロードすると、常に何らかの影響が生じますが、あなたが何をしているのかがわかると思います...
それだけの量のデータを単純にロードすると、多数 (数百万?) のオブジェクトと、同様またはそれ以上の数の参照が作成されます。明らかに x64 を使用したいので、参照が増えますが、パフォーマンスの面で最大の問題はガベージ コレクションです。収集できないオブジェクトがたくさんありますが、GC は大量のメモリを使用していることを認識し、とにかく定期的に試行します。これは、こちらで詳しく調べたものですが、次のグラフはその影響を示しています。特に、これらの「スパイク」はすべて GC キリング パフォーマンスです。

このシナリオ (膨大な量のデータがロードされ、決して解放されない) では、structs を使用するように切り替えました。つまり、データを次の場所にロードします。
struct Foo {
private readonly int id;
private readonly double value;
public Foo(int id, double value) {
this.id = id;
this.value = value;
}
public int Id {get{return id;}}
public double Value {get{return value;}}
}
それらを配列(リストではなく)に直接保存しました:
Foo[] foos = ...
これの重要な点は、これらの構造体のいくつかは非常に大きいため、スタック上で何度も自分自身をコピーしたくないということですが、配列を使用すると次のことができます。
private void SomeMethod(ref Foo foo) {
if(foo.Value == ...) {blah blah blah}
}
// call ^^^
int index = 17;
SomeMethod(ref foos[index]);
オブジェクトを直接渡したことに注意してください- オブジェクトは決してコピーされませんでした。foo.Value
実際には配列の内部を直接見ています。オブジェクト間のリレーションシップが必要な場合は、トリッキーなビットが始まります。これは であるため、ここに参照を保存することはできません。また、それを保存struct
することもできません。ただし、できることは、インデックスを (配列に) 格納することです。例えば:
struct Customer {
... more not shown
public int FooIndex { get { return fooIndex; } }
}
ほど便利ではありませんcustomer.Foo
が、次のようにするとうまくいきます。
Foo foo = foos[customer.FooIndex];
// or, when passing to a method, SomeMethod(ref foos[customer.FooIndex]);
キーポイント:
- 現在、「参照」には半分のサイズを使用しています (an
int
は 4 バイト、x64 の参照は 8 バイト)。
- メモリ内に数百万のオブジェクト ヘッダーがない
- GC が参照する巨大なオブジェクト グラフはありません。GC が信じられないほど迅速に調べることができる少数の配列のみ
- ただし、操作が少し不便で、ロード時に初期処理が必要です
その他の注意事項:
- 文字列はキラーです。何百万もの文字列がある場合、それは問題です。少なくとも、繰り返される文字列がある場合
string.Intern
は、同じ内容の 800,000 個の文字列ではなく、繰り返される各値のインスタンスが 1 つだけになるように、カスタムインターンを実行してください (悪いことではありません)。
- サブリスト/配列ではなく、有限長の繰り返しデータがある場合は、
fixed
配列を検討できます。これにはunsafe
コードが必要ですが、別の無数のオブジェクトと参照を回避します
追加の脚注として、その量のデータでは、シリアル化プロトコル、つまりデータをどのように送信するかについて真剣に考える必要があります。XmlSerializer
、DataContractSerializer
またはのようなものから遠く離れることを強くお勧めしBinaryFormatter
ます。この件に関する指針が必要な場合は、お知らせください。