折叠和缩小之间的区别重新审视

时间:2016-12-29 17:01:24

标签: mapreduce functional-programming reduce fold

我一直在阅读由nice answer提供的Difference between reduce and foldLeft/fold in functional programming (particularly Scala and Scala APIs)?samthebest,我不确定我是否理解所有细节:

  • 根据答案(reduce vs foldLeft):

      

    一个很大的区别(...)是减少应该给予一个可交换的幺半群,(...)

         

    这种区别对于大数据/ MPP /分布式计算非常重要,并且存在减少甚至存在的全部原因。

      

    Reduce正式定义为MapReduce范例的一部分,

    我不确定这两个陈述是如何结合的。任何人都可以对此有所了解吗?

  • 我测试了不同的集合,但我没有看到reducefoldLeft之间的性能差异。看起来ParSeq是一个特例,是吗?

  • 我们真的需要命令来定义fold吗?

      

    我们无法定义折叠,因为块没有排序,折叠只需要关联性,而不是交换性。

    为什么它不能被推广到无序集合?

1 个答案:

答案 0 :(得分:5)

正如评论中所提到的,术语 reduce 在MapReduce的上下文中使用时以及在函数式编程的上下文中使用时意味着不同的东西。

  • 在MapReduce中,系统按给定键对map函数的结果进行分组,然后调用reduce操作来聚合每个组的值(因此reduce是为每个小组打电话一次)。您可以将其视为一个函数(K, [V]) -> R,将组密钥K与属于组[V]的所有值一起使用并产生一些结果。

  • 在函数式编程中,reduce是一个函数,当您为其提供可以组合两个元素的操作时,它会聚合某些集合的元素。换句话说,您定义了一个函数(V, V) -> Vreduce函数使用它将一个集合[V]聚合为一个值V

如果您想使用[1,2,3,4]作为函数添加数字+reduce函数可以通过多种方式执行此操作:

  1. 它可以从头开始计算((1+2)+3)+4)
  2. 它还可以并行计算a = 1+2b = 3+4,然后添加a+b
  3. 根据定义,foldLeft操作始终从左侧开始,因此它始终使用(1)的评估策略。实际上,它也需要初始值,因此它会评估更像(((0+1)+2)+3)+4)的内容。这使得foldLeft对于顺序重要的操作很有用,但这也意味着它无法实现无序集合(因为你不知道"左边"是什么)。