何时使用减少或替代使用pmap

oct*_*bus 1 reduce clojure pmap

编辑:

数据看起来真的像这样.

1,000-00-000,GRABBUS,OCTOPUS ,, M,26-Nev-12,,05 FRENCH TOAST ROAD ,, VACANT,ZA,1867,(001)111-1011,(002)111-1000 ,,

我必须让它看起来很傻,因为它包含专有信息.

这是在使用clojure-csv创建向量向量之前的样子.

我使用解析后的数字来简化它,但它们并没有减少到一个值.我想从clojure-csv解析数据中挑选某些列并创建一个较小的csv行.

如有任何疑惑,请接受我的歉意.

结束编辑:

你如何确定何时使用减少或改为使用pmap?

前段时间,我在博客上发表了关于减少的评论.特别是评论说减少一般不能并行化,但map(pmap)可能是.

何时使用或不使用reduce会产生影响,并且对于以下示例,它会有所作为吗?

谢谢.

(def csv-row [1 2 3 4 5 6 7 8 9])
(def col-nums [0 1 4])

(defn reduce-csv-rowX
    "Accepts a csv-row and a list of columns to extract, and
     reduces the csv-row to the selected list using a list comprehension."
    [csv-row col-nums]
        (for [col-num col-nums
            :let [part-row (nth csv-row col-num nil)]]
            part-row))

(defn reduce-csv-row
    "Accepts a csv-row and a list of columns to extract, and
     reduces the csv-row to the selected list."
    [csv-row col-nums]
    (reduce
        (fn [out-csv-row col-num]
            (let [out-val (nth csv-row col-num nil)]
                (if-not (nil? out-val)
                    (conj out-csv-row out-val))))
        []
        col-nums))
Run Code Online (Sandbox Code Playgroud)

编辑:

(defn reduce-csv-row"接受csv-row和要提取的列列表,并将csv-row缩减为所选列表."[csv-row col-nums](reduce(fn [out-csv- row col-num](让[out-val(nth csv-row col-num nil)](conj out-csv-row out-val)))[] col-nums))

Ret*_*ief 5

通常,您希望使用允许您编写最简单代码的函数.这通常意味着最具体的功能.在这种情况下,您可以将操作视为将列列表转换为列中行的值列表.这对应于map,所以你可能想要使用map.你可以用它来编写它reduce,但在这种情况下,你map在你的调用中重新实现reduce,所以它可能是错误的方法.

但是,有时候reduce是正确的选择.如果您尝试将列表"缩减"为任意值,map则根本无法帮助您.在这种情况下,reduce是您想要的,并且由于您的操作不可并行化,reduce因此也不可并行化.

如果您对reduce代码不理想的原因更感兴趣,如果我们抽象出特定于应用程序的代码,我们就会得到

(reduce
 (fn [out-list current-val]
   (let [out-val (f current-val)]
     (if-not (nil? out-val)
       (conj out-list out-val))))
 []
 col-nums)
Run Code Online (Sandbox Code Playgroud)

一个复杂因素是if-not呼叫.目前,它的越野车-如果out-val是以往任何时候都为零,你会扔掉你已经发现了这一点一切,重新开始(从返回(if-not (nil? out-val) (conj out-list out-val))nil时候out-val是零,所以nil将被用来作为下一个out-list).由于你的其他实现没有任何nil检查,并且这个nil检查是错误的(因此可能从未使用过),我假设它可以被忽略.此时,您的代码是

(reduce
 (fn [out-list current-val]
   (let [out-val (f current-val)]
     (conj out-list out-val)))
 []
 col-nums)
Run Code Online (Sandbox Code Playgroud)

这是一个完全有效的(尽管是非懒惰的)实现map.使用实际调用可以map让您消除所有与您的特定问题实际无关的代码,而是专注于您实际尝试的操作.你可以通过查看ivant的解决方案来看到它的效果.