Text的结构是这样的;
Tag001
0.1, 0.2, 0.3, 0.4
0.5, 0.6, 0.7, 0.8
...
Tag002
1.1, 1.2, 1.3, 1.4
1.5, 1.6, 1.7, 1.8
...
文件可以有任意数量的 TagXXX 事物,每个标签可以有任意数量的 CSV 值行。
==== 购买力平价。(对不起这些东西:-)
更多改进;现在我的 atom 笔记本电脑上 31842 行数据需要 1 秒左右,比原始代码快 7 倍。但是,C 版本比这快 20 倍。
(defn add-parsed-code [accu code]
(if (empty? code)
accu
(conj accu code)))
(defn add-values [code comps]
(let [values comps
old-values (:values code)
new-values (if old-values
(conj old-values values)
[values])]
(assoc code :values new-values)))
(defn read-line-components [file]
(map (fn [line] (clojure.string/split line #","))
(with-open [rdr (clojure.java.io/reader file)]
(doall (line-seq rdr)))))
(defn parse-file [file]
(let [line-comps (read-line-components file)]
(loop [line-comps line-comps
accu []
curr {}]
(if line-comps
(let [comps (first line-comps)]
(if (= (count comps) 1) ;; code line?
(recur (next line-comps)
(add-parsed-code accu curr)
{:code (first comps)})
(recur (next line-comps)
accu
(add-values curr comps))))
(add-parsed-code accu curr)))))
==== PPS。
虽然我不明白为什么第一个比第二个快 10 倍,但不是 slurp,map 和 with-open 确实使阅读速度更快;虽然整个阅读/处理时间并没有减少(从 7 秒到 6 秒)
(time
(let [lines (map (fn [line] line)
(with-open [rdr (clojure.java.io/reader
"DATA.txt")]
(doall (line-seq rdr))))]
(println (last lines))))
(time (let [lines
(clojure.string/split-lines
(slurp "DATA.txt"))]
(println (last lines))))
==== PS。Skuro 的解决方案确实有效。但是解析速度不是那么快,所以我必须使用基于 C 的解析器(它在 1~3 秒内读取 400 个文件,而 clojure 确实需要 1~4 秒的单个文件;是的文件大小相当大)用于读取和仅为统计分析部分构建 DB 和 clojure。