简体   繁体   English

什么是Clojure的可折叠系列?

[英]What is a foldable collection in Clojure?

I am beginner to Clojure, while trying to read about Reducers I found something called foldable collection . 我是Clojure的初学者,在尝试阅读有关Reducers的内容时,我发现了一个叫做可折叠集合的东西。

They are mentioning that vectors and maps are foldable collection, but not the list. 他们提到矢量和地图是可折叠的集合,但不是列表。

I am trying to understand what is foldable collection, why vectors and maps are foldable ? 我想了解什么是可折叠的集合,为什么矢量和地图是可折叠的?

I have not found any definition or explanation for foldable collection. 我没有找到任何可折叠收藏的定义或解释。

The answer is there in the docs, if not quite as clear as it could be: 答案就在文档中,如果不是很清楚的话:

Additionally, some collections (persistent vectors and maps) are foldable. 另外,一些集合(持久性向量和映射)是可折叠的。 The fold operation on a reducer executes the reduction in parallel... 减速机上的折叠操作执行并行减少...

The idea is that, with modern hardware, a "reduction" operation like summing all elements of a vector can be done in parallel. 这个想法是,使用现代硬件,可以并行地完成诸如对矢量的所有元素求和的“缩减”操作。 For example, if summing all elements of a 400K length vector, we could break them up into 4 groups of 100K chunks, sum those in parallel, then combine the 4 subtotals into the final answer. 例如,如果对400K长度向量的所有元素求和,我们可以将它们分成4组100K块,并行求和,然后将4个小计组合成最终答案。 This would be approximately 4x faster than using only a single thread (single cpu core). 这比仅使用单个线程(单个cpu核心)快大约4倍。

Reducers live in the clojure.core.reducers namespace. Reducers存在于clojure.core.reducers命名空间中。 Assume we define aliases like: 假设我们定义了以下别名:

( ns demo.xyz
  (:require [clojure.core :as core]
            [clojure.core.reducers :as r] ))

Compared to clojure.core , we have: clojure.core相比,我们有:

core/reduce   <=>   r/fold     ; new  name for `reduce`
core/map      <=>   r/map      ; same name for `map`
core/filter   <=>   r/filter   ; same name for `filter`

So, the naming is not the best. 所以,命名并不是最好的。 reduce lives in the clojure.core namespace, but there is no reduce in the clojure.core.reducers namespace. reduce生活在clojure.core命名空间,但没有reduceclojure.core.reducers命名空间。 Instead, there is a work-alike function named fold in clojure.core.reducers . 相反,在clojure.core.reducers有一个名为fold的类似工作的函数。

Note that fold is a historical name for combining lists of data as with our summation example. 请注意, fold是用于组合数据列表的历史名称,与我们的求和示例一样。 See the Wikipedia entry for more information. 有关更多信息, 请参阅Wikipedia条目

Because folding accesses the data in non-linear order (which is very ineffecient for linked lists), folding is only worth doing on random-access data structures like vectors). 因为折叠以非线性顺序访问数据(这对于链表来说非常低效),所以折叠仅值于对随机访问数据结构(如向量)进行。


Update #1 : 更新#1

Having said the above, remember the adage that "Premature optimization is the root of all evil." 如上所述,请记住“过早优化是万恶之源”的格言。 Here are some measurements for (vec (range 1e7)) , ie 10M entries, on an 8-core machine: 以下是8核机器上(vec (range 1e7))一些测量值,即10M条目:

(time (reduce + data))

"Elapsed time: 284.52735 msecs"
"Elapsed time: 119.310289 msecs"
"Elapsed time: 98.740421 msecs"
"Elapsed time: 100.58998 msecs"
"Elapsed time: 98.642878 msecs"
"Elapsed time: 105.021808 msecs"
"Elapsed time: 99.886083 msecs"
"Elapsed time: 98.49152 msecs"
"Elapsed time: 99.879767 msecs"

(time (r/fold + data))

"Elapsed time: 61.67537 msecs"
"Elapsed time: 56.811961 msecs"
"Elapsed time: 55.613058 msecs"
"Elapsed time: 58.359599 msecs"
"Elapsed time: 55.299767 msecs"
"Elapsed time: 62.989939 msecs"
"Elapsed time: 56.518486 msecs"
"Elapsed time: 54.218251 msecs"
"Elapsed time: 54.438623 msecs"

Criterium reports: Criterium报道:

reduce   144 ms
r/fold    72 ms

Update #2 更新#2

Rich Hickey talked about the design of transducers/reducers at the 2014 Clojure Conj . Rich Hickey 在2014 Clojure Conj上谈到了传感器/减速器的设计。 You may find these details useful. 您可能会发现这些细节很有用。 The basic idea is that the folding is delegated to each collection type, which uses knowledge of its implementation details to perform the fold efficiently. 基本思想是将折叠委托给每个集合类型,该集合类型使用其实现细节的知识来有效地执行折叠。

Since hash-maps use a vector internally, they can fold in parallel efficiently. 由于哈希映射在内部使用向量,因此它们可以有效地并行折叠。

There is this talk by Guy Steele which predates reducers and might just have served as an inspiration for them. 盖斯·斯蒂尔(Guy Steele)的讲话比减速器早,可能只是为他们提供了灵感。 https://vimeo.com/6624203 https://vimeo.com/6624203

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM