gpt4 book ai didi

Clojure - 处理内存不足的大文件

转载 作者:行者123 更新时间:2023-12-04 21:11:04 24 4
gpt4 key购买 nike

我正在处理 60GB 或更大的文本文件。这些文件被分成可变长度的标题部分和数据部分。我有三个功能:

  • head?区分标题行和数据行的谓词
  • process-header处理一个标题行字符串
  • process-data处理一个数据行字符串
  • 处理函数异步访问和修改内存数据库

  • 我从另一个 SO 线程推进了一种文件读取方法,它应该构建一个惰性的行序列。这个想法是用一个函数处理一些行,然后切换一次函数并继续处理下一个函数。
    (defn lazy-file
    [file-name]
    (letfn [(helper [rdr]
    (lazy-seq
    (if-let [line (.readLine rdr)]
    (cons line (helper rdr))
    (do (.close rdr) nil))))]
    (try
    (helper (clojure.java.io/reader file-name))
    (catch Exception e
    (println "Exception while trying to open file" file-name)))))

    我将它与类似的东西一起使用
    (let [lfile (lazy-file "my-file.txt")]
    (doseq [line lfile :while head?]
    (process-header line))
    (doseq [line (drop-while head? lfile)]
    (process-data line)))

    尽管这可行,但由于以下几个原因,它的效率相当低:
  • 而不是简单地调用 process-head直到我得到数据,然后继续 process-data ,我必须过滤标题行并处理它们,然后重新解析整个文件并删除所有标题行以处理数据。这与 lazy-file 完全相反。打算做的。
  • 观察内存消耗告诉我,该程序虽然看起来很懒惰,但可以使用尽可能多的 RAM 来将文件保存在内存中。

  • 那么使用我的数据库的更有效、更惯用的方法是什么?

    一种想法可能是使用多方法来处理取决于 head? 的值的标题和数据。谓词,但我认为这会对速度产生一些严重的影响,特别是因为只有一次发生谓词结果从始终为真变为始终为假的情况。我还没有对此进行基准测试。

    使用另一种方式构建行序列并使用 iterate 解析它会更好吗? ?这仍然让我需要使用 :while 和 :drop-while,我猜。

    在我的研究中,多次提到使用 NIO 文件访问,这应该可以提高内存使用率。我还不知道如何在 clojure 中以惯用的方式使用它。

    也许我对大体的想法还没有把握,文件应该如何处理?

    与往常一样,非常感谢任何帮助、想法或指向 tuts 的指示。

    最佳答案

    您应该使用标准库函数。

    line-seq、with-open 和 doseq 可以轻松完成这项工作。

    符合以下条件的东西:

    (with-open [rdr (clojure.java.io/reader file-path)]
    (doseq [line (line-seq rdr)]
    (if (head? line)
    (process-header line)
    (process-data line))))

    关于Clojure - 处理内存不足的大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34329821/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com