如何并行化Clojure保持功能?

时间:2015-11-05 19:14:17

标签: clojure parallel-processing

我正在尝试并行化以下功能。我从for语句重构了这个并实现了pmap以加快读取xml数据,这很顺利。下一个瓶颈在我的keep声明中。我怎样才能提高性能?

我已尝试(keep #(when (pmap #(later-date? (second %) after) zip) [(first %) (second %)]) zip)但不允许使用嵌套的#()函数。我还尝试在keep中包装future以及对raw-url-data的调用,但是在调用函数中取消引用会生成nil。

(defn- raw-url-data
  "Parse xmlzip data and return a sequence of URLs/modtime vectors."
  [data after]
  (let [article (xz/xml-> data :url)
        loc (pmap #(-> (xz/xml-> % :loc xz/text) first) article)
        mod (pmap #(-> (xz/xml-> % :lastmod xz/text) first
               parse-modtime) article)
        zip (zipmap loc mod)]
    (keep #(when (later-date? (second %) after)
             [(first %) (second %)]) zip)))

这是我的晚些时候?功能:

(defn- later-date?
  "Return TRUE if DATETIME is after AFTER or either one is NIL."
  [datetime after]
  (or (nil? datetime)
      (nil? after)
      (time/after? datetime after)))

1 个答案:

答案 0 :(得分:2)

有了这种类型的问题,花费时间将数据拆分为并行处理,然后将其重新组合在一起,使其少于按顺序处理数据的时间,这可能很棘手。

在上面的问题中,如果我正确地解释它,你会生成两个数据序列,每个数据并行。因此,在此过程中,这些序列无法相互通信,以查看它们是否具有较晚的日期。完成两个序列的所有数据后,将其形成一个映射。然后将该映射拆分回序列并开始处理它。

第一对日期,(第一个位置)和(第一个暴徒)将会坐下一段时间才能进行比较,看看他们是否应该进入最终结果。所以最好的加速可能来自简单地删除对zipmap的调用。

time/after?速度非常快,因此您可以通过在此处调用pmap来几乎肯定会耗费时间,但无论如何知道如何操作都会很好。您可以通过调用fn之一来解决匿名函数宏无法处理嵌套匿名函数的问题:

(keep (fn [x] (when (pmap #(later-date? (second x) after) zip)) [(first %) (second %)])

另一种方法是

  1. 将其分解为分区,
  2. 对每个分区执行所有处理,
  3. 将它们合并在一起。
  4. 然后调整分区大小,直到您看到分摊成本的好处

    已讨论过herehere