Только одна идея, которая может сохранить память.
Вы можете оставить данные в исходных файлах, а затем просто указать на них из структур в памяти.
Например, это то, что мы делаем для просмотра больших файлов журнала почти мгновенно : мы отображаем в памяти содержимое файла журнала, затем быстро анализируем его, чтобы создать в памяти индексы полезной информации, затем читаем содержание динамически . Строка не создается во время чтения. Только указатели на начало каждой строки с динамическими массивами, содержащими необходимые индексы. Вызов TStringList.LoadFromFile
был бы намного медленнее и занимал бы больше памяти.
Код здесь - см. Класс TSynLogFile
. Хитрость заключается в том, чтобы прочитать файл только один раз и создать все индексы на лету.
Например, вот как мы извлекаем строку текста из содержимого файла UTF-8:
function TMemoryMapText.GetString(aIndex: integer): string;
begin
if (self=nil) or (cardinal(aIndex)>=cardinal(fCount)) then
result := '' else
result := UTF8DecodeToString(fLines[aIndex],GetLineSize(fLines[aIndex],fMapEnd));
end;
Мы используем точно такой же трюк для анализа содержимого JSON . При таком смешанном подходе используются самыми быстрыми библиотеками доступа XML .
Для обработки ваших высокоуровневых данных и быстрого запроса к ним вы можете попытаться использовать динамические массивы записей и наши оптимизированные оболочки TDynArray
и TDynArrayHashed
(в одном блоке). Массивы записей будут занимать меньше памяти, быстрее будут искать, потому что данные не будут раздроблены (даже быстрее, если вы будете использовать упорядоченные индексы или хэши), и вы сможете иметь высокоуровневый доступ к контенту (например, вы можете определить пользовательские функции для извлечения данных из файла отображения памяти). Динамические массивы не подходят для быстрого удаления элементов (или вам придется использовать таблицы поиска) - но вы написали, что не удаляете много данных, поэтому в вашем случае это не будет проблемой.
Таким образом, у вас больше не будет дублирующейся структуры, только логика в ОЗУ и данные в отображаемых в памяти файлах. Я добавил здесь «s», потому что одна и та же логика может прекрасно отображаться в нескольких файлах исходных данных. (вам нужно немного «слить» и «обновить в реальном времени» AFAIK).