大きなjsonファイル(3GB)を解析し、このファイルの各行のハッシュマップを返したい. 私の直感は、トランスデューサを使用してファイルを行ごとに処理し、いくつかの選択されたフィールド (ファイル内のバイトの 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 を超えます。
この場合、変換器は適切ですか? より良い代替手段はありますか?
関数の最後に新しい構造を返すという私の要件の 1 つです。したがって、doseq を使用してファイルをその場で処理することはできません。
さらに、ファイル形式に応じてパーサーとトランスデューサーを変更する必要があります。
ありがとうございました !