Lisp - записывать хэши в файл, используя мало памяти
У меня есть большие хеш-таблицы, которые я иногда записываю на диск в качестве резервной копии. Я обнаружил, что когда я сопоставляю хеш-таблицы и записываю в файл, использование ОЗУ резко возрастает по сравнению с размером хеша.
Я запускаю lisp на emacs со слизью и sbcl 2.0.3.176. Система - Ubuntu 19.10 на сервере dell.
Данные представляют собой несколько уровней хеш-таблиц. Его основная структура:
customer-ht - хеш-таблица структур, называемых заказчиком, с ключом из списков целых чисел, например (1 2), (1 3)
(defstruct customer
(var1 0)
(var2 (make-hash-table))
(var3 (make-hash-table)))
Хеш-таблица var2 - это простой ключ / значение, где ключи - это целые числа 1, 2 и т.д., а значение всегда 'T
В хэш-таблице var3 есть ключи, которые являются целыми числами, а ее значение - это другая хеш-таблица, где ключи представляют собой списки целых чисел (1 2 3) (1 5 7), а значение всегда равно 'T
Итак, у покупателя (1 2)
var1 = 5,
var2 = хэш-таблица ключа 3, значение 'T
var3 = хэш-таблица ключа 9, значение = хэш-таблица ключа (5 6 7), значение 'T
Я использую это для сопоставления и записи в файл:
(defun write-cust-to-file (filename)
(with-open-file s filename
:direction :output
:if-exists :supersede
(maphash
#'(lambda (cust-key cust-data)
(format s "~A ~A~%" cust-key customer-var1)
(maphash
#'(lambda (k1 v1)
(declare (ignore v1))
(format s "~A ~A~%" cust-key k1))
(customer-var2 cust-data))
(maphash
#'(lambda (k1 v1)
(maphash
#'(lambda (k2 v2)
(declare (ignore v2))
(format s "~A ~A~%" (list cust-key "X" k1) k2))
v1)))
(customer-var3 cust-data)))
customer-ht))
nil)
В структуре больше таких переменных, которые написаны с использованием одного и того же кода maphash/write. Итак, каждая структура клиентов довольно большая.
Когда я запускаю это, моя оперативная память взрывается. Все мои данные в ОЗУ составляют около 20 ГБ. Когда я запускаю это, он достигает 40 ГБ +. Я начинаю думать, что хеши карты дублируют данные из структур по мере их выполнения. Если я запускаю аналогичную функцию записи в разделе maphash выше, который использует k1 и k2 (2 вложенных сопоставления) для хеша, у которого нет структуры, увеличения памяти не происходит.
Есть ли способ записи в файл в LISP, который не использует дополнительную оперативную память (или, по крайней мере, очень мало)? Я снизлю производительность, чтобы сэкономить оперативную память.