Lisp-使用低内存占用量写入文件

问题描述 投票:1回答:1

我有大的哈希表,偶尔会写到磁盘上。我发现,在映射哈希表并将其写入文件时,与哈希值的大小相比,RAM使用率飞速增长。

我正在使用粘液和sbcl 2.0.3.176在emacs上运行lisp。系统是Dell服务器上的Ubuntu 19.10。

数据是哈希表的多个级别。它的基本结构是:

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)

结构中有更多这样的var,它们都是使用相同的maphash / write代码编写的。因此,每个客户结构都很大。

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

是否有一种方法可以在不使用任何额外RAM(或至少很少的RAM)的LISP中写入文件?我将在性能方面有所帮助,以节省我的RAM。

其他信息:运行此命令时,我运行了dstat,发现写入磁盘不连续。大约每30秒写入一次大块(20MB-120MB),每5秒左右写入一次12K小块。此外,在函数完成写入之前,RAM使用量达到最高。那么,数据是否在等待写入磁盘时存储在某处?还是只是分配一些内存?运行(gc:full'T)后缀将恢复所有额外的RAM。

我有大的哈希表,偶尔会写到磁盘上。我发现在映射哈希表并将其写入文件时,与哈希值的大小相比,RAM使用率飞速增长。 ...

file memory lisp common-lisp write
1个回答
0
投票

尝试loop遍历哈希表。

© www.soinside.com 2019 - 2024. All rights reserved.