你能解释一下pmap的懒惰和记忆足迹吗?

时间:2018-03-23 23:19:43

标签: clojure

文档说明了pmap

  

与地图类似,除了f并行应用。半懒在那   并行计算保持在消费之前,但没有   除非需要,否则实现整个结果。

你能否在一些简单的背景下对这两个陈述进行混淆? 还有pmap函数,一个doseq等价,相对于迭代集合的大小,内存占用量是否恒定?

2 个答案:

答案 0 :(得分:2)

  

半懒惰,因为并行计算保持在消耗之前

这意味着pmap将比序列消费者严格要求的工作略多一些。这是"提前工作"最小化在消耗序列时等待更多项目的等待。例如,如果你并行计算一些无限序列而你只消耗了前50个结果,那么pmap可能会前进并计算50 + N.

  

但除非需要,否则不会实现整个结果。

这意味着它只能提前工作到某个阈值。除非它被完全消耗(或几乎完全消耗),否则整个序列都不会产生。

  

还有pmap函数,doseq等效函数

您可以doalldorun使用pmap并行生成副作用。

这里是所有三个一起的例子,使用无限序列作为pmap的输入:

(def calls (atom 0))
(dorun (take 50 (pmap (fn [_] (swap! calls inc)) (range))))
;; @calls => 60

完成此操作后,calls的值将超过50,即使我们只消耗了序列中的50个项目。

另请阅读reducers和core.async以了解其他相同方法。

答案 1 :(得分:1)

虽然泰勒的答案是正确的,但几年前我还在Clojure West上介绍了pmap内部发生的事情,以及它是如何变得懒惰的。我知道不是每个人都喜欢用于学习的视频,但如果你这样做,它可能会有所帮助:https://youtu.be/BzKjIk0vgzE?t=11m48s

(如果你想要非懒惰的pmap,我认可的是Claypoole。)