Какой самый эффективный способ управлять большими объемами данных (данными о высоте) и заменить этот огромный массив? - PullRequest
5 голосов
/ 06 июня 2011

Мне нужно быстро просмотреть эти данные и получить доступ ко всем этим данным.К сожалению, мне также нужно сохранить память (некоторые из них приведут к OutofMemoryExceptions)

short[,,] data = new short[8000,8000,2];

Я попытался сделать следующее:

  • попробовал неровный массив - те же проблемы с памятью
  • попытался разбить на меньшие массивы - все еще возникают проблемы с памятью
  • Единственное разрешение - эффективно сопоставить эти данные с использованием файла с отображенной памятью или есть какой-то другой способ сделать это?

Ответы [ 5 ]

5 голосов
/ 07 июня 2011

Как насчет базы данных ? Ведь они созданы для этого.

Я бы посоветовал вам взглянуть на базу данных NoSQL . В зависимости от ваших потребностей, существуют также базы данных в памяти [которые, очевидно, могут страдать от той же проблемы нехватки памяти] и базы данных, которые можно копировать, развернуть или связать с вашим приложением.

Я бы не хотел связываться с подробностями хранения вручную, а файлы отображения памяти - это то, что некоторые базы данных (по крайней мере, MongoDB) делают внутри. По сути, вы бы катили свою собственную БД, и написание базы данных не тривиально - даже если вы сузите вариант использования.

Redis или Membase звучат как подходящие альтернативы для вашей проблемы. Насколько я вижу, оба способны управлять использованием оперативной памяти за вас, то есть считывать данные с диска по мере необходимости и кэшировать данные в оперативной памяти для быстрого доступа. Конечно, здесь будут играть роль ваши шаблоны доступа.

Имейте в виду, что много усилий было потрачено на создание этих БД. Согласно Википедии, Zynga использует Membase , а Redis спонсируется VMWare.

1 голос
/ 07 июня 2011

Вы уверены, что вам нужен доступ ко всему этому постоянно? ... или вы могли бы загрузить его часть, затем перейти к следующему?

Не могли бы вы обойтись без использования mip-mapping или LoD представлений, если это просто данные высоты? Оба из них могут позволить вам удерживать более низкие разрешения до тех пор, пока вам не понадобится загрузить определенные фрагменты данных с более высоким разрешением.

Сколько свободной памяти у вас на машине? Какую операционную систему ты используешь? Это 64 бит?

Если вы выполняете операции, интенсивно использующие память / обработку, рассматривали ли вы возможность реализации тех частей в C ++, где вы имеете больший контроль над такими вещами?

Трудно помочь вам гораздо дальше, не зная некоторых особенностей вашей системы и того, что вы на самом деле делаете со своими данными ...?

0 голосов
/ 07 июня 2011

.NET хранит шорты как 32-битные значения, даже если они содержат только 16 бит.Таким образом, вы можете сэкономить фактор два, используя массив целых чисел и расшифровав int в два шорта самостоятельно, используя битовые операции.

Тогда у вас есть наиболее эффективный способ хранения такого массива.Тогда вы можете сделать следующее:

  1. Использовать 64-битный компьютер.Затем вы можете выделить много памяти, и операционная система позаботится о том, чтобы перенести данные на диск для вас, если у вас закончится ОЗУ (убедитесь, что у вас достаточно большой файл подкачки).Затем вы можете использовать 8 TERA-байтов данных (если у вас достаточно большой диск).

  2. Считывать части этих данных с диска по мере необходимости, вручную, используя файловый ввод-вывод или отображение памяти.

0 голосов
/ 07 июня 2011

Как вы взаимодействуете с этим большим многомерным массивом? Вы используете рекурсию? Если это так, убедитесь, что ваши рекурсивные методы передают параметры по ссылке, а не по значению.

Кстати, вам нужно, чтобы 100% этих данных были доступны одновременно? Лучший способ справиться с большими объемами данных - это через поток или какой-либо объект для чтения. Попробуйте разобраться с данными по сегментам. У меня есть несколько процессов, которые имеют дело с данными Gigs, и он может обрабатывать их в небольшом объеме памяти из-за того, что я передаю их через SqlDataReader.

TL; DR: посмотрите, как вы передаете данные между вызовами функций O (ref) и, возможно, используете потоковые шаблоны для обработки данных небольшими порциями.

надеюсь, это поможет!

0 голосов
/ 07 июня 2011

Я бы не рекомендовал традиционную реляционную базу данных, если вы выполняете численные расчеты с этими данными.Я подозреваю, что здесь вы сталкиваетесь не с размером самих данных, а с известной проблемой .NET под названием Фрагментация кучи больших объектов .Если после частого размещения этих буферов у вас возникают проблемы (даже если они должны собираться мусором), это, вероятно, ваш виновник.Лучшее решение - сохранить столько буферов, сколько вам нужно, предварительно выделив их, и использовать их повторно, чтобы предотвратить перераспределение и последующую фрагментацию.

...