Clojure:减速器的第一步

为了准备下周的演讲,我今天一直在和Clojure玩耍,发现自己编写了以下代码,将相同的功能应用于三个不同的分数:

(defn log2 [n]
  (/ (Math/log n) (Math/log 2)))
 
(defn score-item [n]
  (if (= n 0) 0 (log2 n)))
 
(+ (score-item 12) (score-item 13) (score-item 5)) 9.60733031374961

我忘了折叠一个集合,但是很快想起,可以使用以下代码实现相同的结果:

(reduce #(+ %1 (score-item %2)) 0 [12 13 5]) 9.60733031374961

这里的附加优点是,如果我想将第4个乐谱添加到混音中,我所需要做的就是将其附加到向量的末尾:

(reduce #(+ %1 (score-item %2)) 0 [12 13 5 6]) 12.192292814470767

但是,在Googling提醒自己要减少参数的顺序时,我不断浏览有关听说过但从未使用过的关于reducer的文章和文档

据我了解,它们习惯于提高性能并简化集合中函数​​的组合,因此我不确定它们对我有多大帮助,但我想我会尝试一下。

我们的第一步是将名称空间纳入范围:

(require ' [ clojure.core.reducers :as r])

现在,我们可以使用reduce函数计算相同的结果:

(r/reduce #(+ %1 (score-item %2)) 0 [12 13 5 6]) 12.192292814470767

到目前为止,完全相同。 如果我们要计算单个分数,然后过滤掉低于某个阈值的分数,则代码的行为会有所不同:

(->>[12 13 5 6]
    (map score-item)
    (filter #(> % 3))) (3.5849625007211565 3.700439718141092)
 
(->> [12 13 5 6]
     (r/map score-item)
     (r/filter #(> % 3))) #object [ clojure.core.reducers$folder$reify__19192 0x5d0edf21 " clojure.core.reducers$folder$reify__19192@5d0edf21 "]

而不是给我们分数的矢量减速机版本返回减速可以传递到减少折叠 ,如果我们希望有一个积累的结果,或者 ,如果我们要输出的集合。 在这种情况下,我们希望后者:

(->> [12 13 5 6]
     (r/map score-item)
     (r/filter #(> % 3))
     (into [])) (3.5849625007211565 3.700439718141092)

对于一个只有4个项目的集合,我认为减速器不会在这里提供很大的速度改进,但是如果我们希望并行处理集合,就需要使用fold函数。

下一次!

翻译自: https://www.javacodegeeks.com/2016/01/clojure-first-steps-reducers.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值