私はとても幸せだ!:)最近、私は主題の問題を試しました-データベースを使用してそれを解決しようとしましたが、この方法は完璧にはほど遠いことがわかりました。マトリックス[20000,20000]は単一のテーブルとして実装されました。インデックスを適切に設定しても、4億を超えるレコードを作成するために必要な時間は、私のPCでは約1時間です。それは私にとって重要ではありません。次に、その行列を処理するためにアルゴリズムを実行し(同じテーブルを結合するには、2回必要です!)、30分以上動作した後、1つのステップも実行されませんでした。その後、唯一の方法は、メモリ内でのみそのようなマトリックスを操作し、C#に戻る方法を見つけることであると理解しました。
パイロットアプリケーションを作成して、メモリ割り当てプロセスをテストし、さまざまな構造を使用して割り当てプロセスが停止する場所を特定しました。
私の最初の投稿で述べたように、 32ビットWinXPでは約650MBの2次元アレイを使用して割り当てることができます。Win7と64ビットコンパイルを使用した後の結果も悲しいものでした-700MB未満。
単一の2次元配列[、]の代わりにJAGGED ARRAYS [] []を使用しました。結果は、以下のとおりです。
リリースモードで32ビットアプリとしてコンパイル-WinXP32ビット3GBphys。mem。-1.45GB
を64ビットアプリとしてリリースモードでコンパイル-VMでWin764ビット2GB - 7.5GB
-テストに使用したアプリケーションのソースは、この投稿に添付されています。ソースファイルを添付する方法がここに見つからないので、設計部分を説明し、ここに手動コードを入れてください。WinFormsアプリケーションを作成します。デフォルトの名前(ボタン1つ、numericUpDown 1つ、リストボックス1つ)を使用して、このようなコントロールをフォームに配置します。.csファイルに次のコードを追加して実行します。
private void button1_Click(object sender, EventArgs e)
{
//Log(string.Format("Memory used before collection: {0}", GC.GetTotalMemory(false)));
GC.Collect();
//Log(string.Format("Memory used after collection: {0}", GC.GetTotalMemory(true)));
listBox1.Items.Clear();
if (string.IsNullOrEmpty(numericUpDown1.Text )) {
Log("Enter integer value");
}else{
int val = (int) numericUpDown1.Value;
Log(TryAllocate(val));
}
}
/// <summary>
/// Memory Test method
/// </summary>
/// <param name="rowLen">in MB</param>
private IEnumerable<string> TryAllocate(int rowLen) {
var r = new List<string>();
r.Add ( string.Format("Allocating using jagged array with overall size (MB) = {0}", ((long)rowLen*rowLen*Marshal.SizeOf(typeof(int))) >> 20) );
try {
var ar = new int[rowLen][];
for (int i = 0; i < ar.Length; i++) {
try {
ar[i] = new int[rowLen];
}
catch (Exception e) {
r.Add ( string.Format("Unable to allocate memory on step {0}. Allocated {1} MB", i
, ((long)rowLen*i*Marshal.SizeOf(typeof(int))) >> 20 ));
break;
}
}
r.Add("Memory was successfully allocated");
}
catch (Exception e) {
r.Add(e.Message + e.StackTrace);
}
return r;
}
#region Logging
private void Log(string s) {
listBox1.Items.Add(s);
}
private void Log(IEnumerable<string> s)
{
if (s != null) {
foreach (var ss in s) {
listBox1.Items.Add ( ss );
}
}
}
#endregion
問題は私のために解決されました。皆さん、よろしくお願いします!