Concurrency 并行处理Clojure中的CSV文件

Concurrency 并行处理Clojure中的CSV文件,concurrency,clojure,Concurrency,Clojure,我有一个很大的CSV文件,其中包含独立的项目,需要花费相当多的精力来处理。我希望能够并行处理每个行项目。我在这里找到了一段用于处理CSV文件的示例代码: 代码是: (use '(clojure.contrib duck-streams str-utils)) ;;' (with-out-writer "coords.txt" (doseq [line (read-lines "coords.csv")] (let [[x y z p] (re-spl

我有一个很大的CSV文件,其中包含独立的项目,需要花费相当多的精力来处理。我希望能够并行处理每个行项目。我在这里找到了一段用于处理CSV文件的示例代码:

代码是:

(use '(clojure.contrib duck-streams str-utils))                 ;;'
(with-out-writer "coords.txt"
  (doseq [line (read-lines "coords.csv")]
    (let [[x y z p] (re-split #"," line)]
      (println (str-join \space [p x y z])))))
这是能够打印出数据从我的CSV文件,这是伟大的-但它只使用了一个CPU。我尝试过各种不同的方法,结果是:

(pmap println (read-lines "foo"))
这在交互模式下可以正常工作,但在从命令行运行时不起任何作用。从IRC上的对话中可以看出,这是因为默认情况下stdout对线程不可用

实际上,我要寻找的是一种习惯性地将函数应用于CSV文件的每一行并并行执行的方法。如果可能的话,我还想在测试期间将一些结果打印到stdout


有什么想法吗?

如果你想快速完成这项工作,你可能想看看关于Alex Osborne如何解决Tim Bray提出的Widefinder 2挑战的文章。Alex深入分析、处理和收集结果的各个方面(在Widefinder 2中,该文件是一个非常大的Apache日志)。实际使用的代码是。

如果希望输出结果与输入结果的顺序相同,则从pmap打印可能不是一个好主意。我建议在上面创建一个输入行pmap的(惰性)序列,然后打印pmap的结果。 像这样的方法应该会奏效:

(dorun (map println (pmap expensive-computation (read-lines "coords.csv"))))

如果hat代码可以通过使用更多内核来加速,我会非常惊讶。我99%确定,这里的实际速度限制是文件I/O,它应该比解决这个问题的任何单个内核都慢几个数量级

除了在多个CPU上拆分这些非常小的任务时引入的开销之外。pmap并不是完全免费的


如果您确信磁盘IO不会成为问题,并且您有很多CSV解析要做,那么只需在自己的线程中解析多个文件,您就可以用更少的工作获得更多的收益。

解析和处理每个CSV行平均需要大约5秒的时间,因此这肯定有助于使其并行化。我同意这种工作通常是I/O而不是计算限制的。那篇文章实际上很有帮助。我一定会更深入地再读一遍!第一个链接是断链,修复了链接。csv文件上的“读取行”可能会生成混乱的数据,因此最好使用成熟的csv处理库。