0

我有大型哈希表,我将其写入磁盘作为偶尔的备份。我发现当我映射哈希表并写入文件时,与哈希的大小相比,RAM 的使用量猛增。

我在带有 slime 和 sbcl 2.0.3.176 的 emacs 上运行 lisp。系统是戴尔服务器上的 Ubuntu 19.10。

数据是多层次的哈希表。它的基本结构是:

customer-ht - 称为 customer 的结构哈希表,以整数列表为键,如 (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 代码编写的。因此,每个客户结构都非常大。

当我运行它时,我的 RAM 会爆炸。我在 RAM 中的所有数据都在 20GB 左右。当我运行它时,它达到 40GB+。我开始认为 maphashes 在运行时会从结构中复制数据。如果我对上面的 maphash 部分运行类似的写入函数,该函数在没有结构的哈希上使用 k1 和 k2(2 个嵌套映射),则不会发生内存增加。

有没有一种方法可以在不使用任何额外 RAM(或至少很少)的 LISP 中写入文件?我会降低性能以节省我的 RAM。

4

0 回答 0