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, который не использует дополнительную оперативную память (или, по крайней мере, очень мало)? Я снизлю производительность, чтобы сэкономить оперативную память.

0 ответов

Другие вопросы по тегам