Реализованный в память файл реализации IList, для хранения больших наборов данных «в памяти»? - PullRequest
7 голосов
/ 14 сентября 2011

Мне нужно выполнять операции в хронологическом порядке на огромных временных рядах, реализованных в виде IList. Данные в конечном итоге сохраняются в базе данных, но не имеет смысла отправлять десятки миллионов запросов в базу данных.

В настоящее время IList в памяти вызывает исключение OutOfMemory при попытке сохранить более 8 миллионов (маленьких) объектов, хотя мне потребуется иметь дело с десятками миллионов.

После некоторых исследований, похоже, что лучший способ сделать это - сохранить данные на диске и получить к ним доступ через оболочку IList.

Файлы с отображением в памяти (представленные в .NET 4.0) кажутся подходящим интерфейсом для использования, но мне интересно, как лучше написать класс, который должен реализовывать IList (для простого доступа) и внутренне иметь дело с отображенным в память файлом.

Мне также любопытно услышать, если вы знаете о других способах! Я подумал, например, об обертке IList, использующей данные из db4o ( кто-то упомянул здесь , использующий файл с отображением в памяти в качестве IoAdapterFile, хотя использование db4o, вероятно, повышает производительность по сравнению с работой непосредственно с файлом, отображенным в память ).

Я встречал этот вопрос , заданный в 2009 году, но он не дал полезных ответов или серьезных идей.

Ответы [ 3 ]

8 голосов
/ 14 сентября 2011

Я нашел это PersistentDictionary <> , но он работает только со строками, и, читая исходный код, я не уверен, что он был разработан для очень больших наборов данных.

Более масштабируемый (до 16 ТБ), ESENT PersistentDictionary <> , использует ядро ​​базы данных ESENT, присутствующее в Windows (XP +), и может хранить все сериализуемые объекты, содержащие простые типы.

На основе дискаСтруктуры данных, включая Dictionary, List и Array с «интеллектуальным» сериализатором , выглядели точно так же, как я искал, но они не работали гладко с очень большими наборами данных, тем более, что они не используют «нативный».NET MemoryMappedFiles пока нет, и поддержка 32-битных систем является экспериментальной.

Обновление 1 : я закончил тем, что реализовал свою собственную версию, которая широко использует .NET MemoryMappedFiles;это очень быстро, и я, вероятно, выпущу его на Codeplex, как только сделаю его лучше для более общего использования.

Обновление 2 : TeaFiles.Net также работаетотлично подходит для моей цели.Настоятельно рекомендуется (и бесплатно).

3 голосов
/ 14 сентября 2011

вижу несколько вариантов:

  • "в памяти-БД"
    например, SQLite можно использовать таким образом - не нужно никаких настроек и т. д. просто разверните DLL (1 или 2) вместе с приложением, а все остальное можно сделать программно
  • Загрузка всех данных во временную таблицу (таблицы) в БД с неизвестными (но большими) объемами данных. Я обнаружил, что это окупается очень быстро (и обработку обычно можно выполнять внутри БД, что даже лучше!)
  • используйте MemoryMappedFile и фиксированный размер структуры (доступ в виде массива через смещение), но имейте в виду, что физическая память является пределом, за исключением того, что вы используете своего рода «скользящее окно» для отображения только частей в память
1 голос
/ 14 сентября 2011

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

Лучше всего, вероятно, придумать фиксированный размер структуры при сохранении в памяти (если вы можете), тогда вы используете смещение в качествеидентификатор элемента спискаОднако удаление / сортировка всегда является проблемой.

...