gpt4 book ai didi

clojure - 使用 Clojure Transducers 解析大文件 : OutOfMemory Error

转载 作者:行者123 更新时间:2023-12-02 20:11:16 27 4
gpt4 key购买 nike

我想解析一个大的 json 文件 (3GB) 并返回该文件中每一行的 HashMap 。我的直觉是使用转换器逐行处理文件,并用一些选定的字段(> 文件中字节的 5%)构造一个向量。

但是,以下代码会抛出 OutOfMemory 异常:

文件.json

{"experiments": {"results": ...}}
{"experiments": {"results": ...}}
{"experiments": {"results": ...}}

解析器.clj

(defn load-with!
"Load a file using a parser, a structure and a transducer."
[parser structure xform path]
(with-open [r (clojure.java.io/reader path)]
(into structure xform (parser r))))

(def xf (map #(get-in % ["experiments" "results"])))
(def parser (comp (partial map cheshire.core/parse-string) line-seq))

(load-with! parser (vector) xf "file.json")

当我使用 JVisualVM 可视化进程时,堆会随着时间的推移而增长,并在进程崩溃之前超过 25 GB。

传感器适合这种情况吗?有更好的选择吗?

我的要求之一是在函数末尾返回新结构。因此,我无法使用doseq就地处理文件。

此外,我需要根据文件格式更改解析器和转换器。

谢谢!

最佳答案

你已经很接近了。我不知道 json/parse-string 的作用,但它是否与 here 中的 json/read-str 相同那么这段代码应该就是你想要做的事情。

看起来你想要这样的东西:

(require '[clojure.data.json :as json])
(require '[clojure.java.io :as java])

(defn load-with!
"Load a file using a parser, a structure and a transducer."
[parser structure xform path]
(with-open [r (java/reader path)]
(into structure (xform (parser r)))))

(def xf (partial map #(get-in % ["experiments" "results"])))

(def parser (comp (partial map json/read-str) line-seq))


(load-with! parser [] xf "file.json")

我猜这些只是将所有业务细节删除到这里的最小示例中所犯的错误。使用下面的代码我能够处理一个大文件,上面的代码给了我一个 OOM 错误:

(require '[clojure.data.json :as json])
(require '[clojure.java.io :as java])

(def structure (atom []))

(defn do-it! [xform path]
(with-open [r (java/reader path)]
(doseq [line (line-seq r)]
(swap! structure conj (xform line)))))

(defn xf [line]
(-> (json/read-str line)
(get-in ["experiments" "results"])))

(do-it! xf "file.json")

(take 10 @structure)

关于clojure - 使用 Clojure Transducers 解析大文件 : OutOfMemory Error,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40193129/

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