Clojure - 加速大文件处理
Clojure - Speed up large file processing
我需要读取大文件 (~1GB)、处理它并保存到数据库。我的解决方案是这样的:
data.txt
格式:[id],[title]\n
1,Foo
2,Bar
...
代码
(ns test.core
(:require [clojure.java.io :as io]
[clojure.string :refer [split]]))
(defn parse-line
[line]
(let [values (split line #",")]
(zipmap [:id :title] values)))
(defn run
[]
(with-open [reader (io/reader "~/data.txt")]
(insert-batch (map parse-line (line-seq reader)))))
; insert-batch just save vector of records into database
但是这段代码并不能很好地工作,因为它首先解析所有行,然后将它们发送到数据库中。
我认为理想的解决方案是 read line -> parse line -> collect 1000 parsed lines -> batch insert them into database -> repeat until there is no lines
。不幸的是,我不知道如何实现它。
一条建议:
使用line-seq得到惰性行序列,
使用map解析每一行,
(到目前为止这与您正在做的相符)
使用partition-all将你的惰性解析行序列分成批次,然后
使用 insert-batch with doseq 将每个批次写入数据库。
还有一个例子:
(->> (line-seq reader)
(map parse-line)
(partition-all 1000)
(#(doseq [batch %]
(insert-batch batch))))
我需要读取大文件 (~1GB)、处理它并保存到数据库。我的解决方案是这样的:
data.txt
格式:[id],[title]\n
1,Foo
2,Bar
...
代码
(ns test.core
(:require [clojure.java.io :as io]
[clojure.string :refer [split]]))
(defn parse-line
[line]
(let [values (split line #",")]
(zipmap [:id :title] values)))
(defn run
[]
(with-open [reader (io/reader "~/data.txt")]
(insert-batch (map parse-line (line-seq reader)))))
; insert-batch just save vector of records into database
但是这段代码并不能很好地工作,因为它首先解析所有行,然后将它们发送到数据库中。
我认为理想的解决方案是 read line -> parse line -> collect 1000 parsed lines -> batch insert them into database -> repeat until there is no lines
。不幸的是,我不知道如何实现它。
一条建议:
使用line-seq得到惰性行序列,
使用map解析每一行,
(到目前为止这与您正在做的相符)
使用partition-all将你的惰性解析行序列分成批次,然后
使用 insert-batch with doseq 将每个批次写入数据库。
还有一个例子:
(->> (line-seq reader)
(map parse-line)
(partition-all 1000)
(#(doseq [batch %]
(insert-batch batch))))