Я так счастлив! :) Недавно я обшарил предметную проблему - попытался решить ее с помощью базы данных, но обнаружил, что этот путь далеко не идеален. Матрица [20000,20000] была реализована в виде единой таблицы.
Даже при правильно настроенных индексах время, необходимое только для создания более 400 миллионов записей, составляет около 1 часа на моем ПК. Это не критично для меня.
Затем я запустил алгоритм для работы с этой матрицей (требуется два раза, чтобы объединить одну и ту же таблицу!), И после того, как он проработал более получаса, он не сделал ни одного шага.
После этого я понял, что единственный способ - найти способ работать с такой матрицей только в памяти и снова вернуться к C #.
Я создал пилотное приложение, чтобы протестировать процесс выделения памяти и определить, где именно процесс выделения останавливается, используя разные структуры.
Как было сказано в моем первом посте, можно использовать 2-мерные массивы только для 650MB под 32-битным WinXP.
Результаты после использования Win7 и 64-битной компиляции также были печальными - менее 700MB.
Я использовал JAGGED ARRAYS [] [] вместо одного 2-мерного массива [,], и результаты вы можете увидеть ниже:
Скомпилировано в режиме Release как 32-битное приложение - WinXP 32bit 3GB физ. памятная записка - 1,45 ГБ
Скомпилировано в режиме Release как 64-битное приложение - Win7 64-битная 2 ГБ под виртуальной машиной - 7.5 ГБ
- К этому посту прилагаются источники приложения, которые я использовал для тестирования.
Я не могу найти здесь, как прикрепить исходные файлы, поэтому просто опишите часть дизайна и поместите здесь ручной код.
Создать приложение WinForms.
Поставьте на форму такие контролы с именами по умолчанию:
1 кнопка, 1 numericUpDown и 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
Проблема решена для меня. Ребята, заранее спасибо!