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))))