GPars(3):并发集合之Map-Reduce

Map-Reduce DSL与Parallelizer类的xxxParallel方法族目的一样。但在多个并行方法连续作用于同一集合时,Map-Reduce执行效率就相当高了。

GPars(2):并发集合之Parallelizer一文中介绍的xxxParellel方法与其对应的非并行方法是对等体,也就是说,每次方法调用之后的返回的集合是普通Groovy集合(比如collectParallel()与collect()的返回结果是一致的,只是并行与非并行处理的区别)。在并行执行完所需操作并返回结果之前,所构造的Parallel Array会被销毁,变成普通集合。因此,如果要对同一集合连续运用并行方法时,需要反复构造、销毁Parallel Array。

Map/Reduce则不同,把集合变成Parallel Array的过程只会进行一次,当然也只需销毁一次。在连续使用Map/Reduce方法时,直接传递的是内部Parallel Array,这样效率就大大提高了。例如,下例是并发计算所有URL访问结果中包含GROOVY词语(按空格分隔)的数目(一条词语中有多个"Groovy"的只计一次):

import groovyx.gpars.Parallelizer
Parallelizer.doParallel{
    def urls=["http://groovy.codehaus.org","http://www.google.com"]
    println 'Number of occurrences of the word GROOVY today: ' 
           + urls.parallel
            .map {it.toURL().text.toUpperCase()}
            .filter {it.contains('GROOVY')}
            .map{it.split()}
            .map{it.findAll{word -> word.contains 'GROOVY'}.size()}
            .sum()
}

运行结果是:

Number of occurrences of the word GROOVY today: 153

注意:运行结果会随网站内容的变化而变化,所以你运行的结果不等于153也是合理的。

Map/Reduce方法列表如下(参见groovyx.gpars.ParallelCollection类):

  • map()
  • reduce()
  • filter()
  • size()
  • sum()
  • min()
  • max()

若要返回普通Groovy集合实例,只需使用collection属性即可

import groovyx.gpars.Parallelizer
Parallelizer.doParallel{
    def myNumbers = (1..1000).parallel
                             .filter{it % 2 == 0}
                             .map{Math.sqrt it}
                             .collection
}

本系列的其他文章:

By songwei - Posted on 03 三月 2010