【问题标题】:Parallel Stream in scalascala中的并行流
【发布时间】:2017-07-07 02:42:50
【问题描述】:

是否有任何(希望是开箱即用的)方法来并行遍历 Scala 流?

例如,看看这个 java 8 代码:

String[] s = {"a","b","c","d","e"};
List<String> list = Arrays.asList(s);
list.parallelStream().forEach(System.out::println);

这将并行打印所有列表流内容.. 但是,据我了解,scala 中的流是连续的。

有什么解决方法吗?

编辑: 请注意,流允许我们在数据到达时对其进行处理。然后,如果不需要数据,请将它们从内存中删除。 例如:

"abcd".toStream.filter { x => 
  println(s"1 filter $x")  
   if(x.toInt%2==0) true;else false;
  } //end of first block
  .foreach { x => 
  println(s"2 filter->$x")  
  } //end of second block

将输出如下内容:

1 个过滤器

1 个过滤器 b

2 过滤器->b

1 个过滤器 c

1 个过滤器 d

2 过滤器->d

另一方面,下面的代码将分块处理数据。在每次转换时将变量保存在内存中:

  "abcd".toVector.par.filter { x => 
  println(s"1 filter $x")  
   if(x.toInt%2==0) true;else false;
  } //end of first block
  .foreach { x => 
  println(s"2 filter->$x")  
  } //end of second block

输出: 1个过滤器c

1 个过滤器

1 个过滤器 b

1 个过滤器 d

2 过滤器->b

2 过滤器->d

【问题讨论】:

  • 除了下面提供更多信息的答案之外,这里还有一个可以做你想做的事情:('a' to 'e').par.foreach(println _)
  • @evan.oman 我认为目前的任何答案都不能解决这个问题

标签: java scala


【解决方案1】:

许多(大多数?)Scala 集合都有一个par 方法,可以“返回此集合的并行实现”。

来自 ScalaDocs:

对于大多数集合类型,此方法通过复制所有元素来创建一个新的并行集合。对于这些集合,par 需要线性时间。

Scala 的Stream[] 没有直接的并行实现,因此您会得到ParSeq[],并且由于ParSeq 是一个特征,REPL 会将其实例化为ParVector

scala> Stream("a","b","c","d","e").par
res0: scala.collection.parallel.immutable.ParSeq[String] = ParVector(a, b, c, d, e)

另外值得注意的是 ScalaDocs 中其他地方的信息:

传递给某些操作的高阶函数可能包含副作用。由于批量操作的实现可能不是顺序的,这意味着副作用可能无法预测,如果不注意可能会产生数据争用、死锁或状态无效。在访问可变数据时,程序员应避免使用副作用或使用某种形式的同步。

因此,您的 foreach(println) 代码可能会产生不可预测/不受欢迎的结果。

【讨论】:

    【解决方案2】:

    你可以使用parallel collections

    import scala.collection.parallel.immutable.ParVector
    
    val pv = new ParVector[Int]
    
    val pv = Vector(1,2,3,4,5,6,7,8,9).par
    
    pv.foreach(x => println(x));
    

    【讨论】:

    • 但是 ParVector 的行为不像 jdk8 流。 :c
    【解决方案3】:

    目前,我知道两种可能有用的可能性。

    当然,假设您在 JVM 上运行 Scala,您应该能够直接使用 Java 8 Stream API。

    或者,我认为您可能会调查 Apache Spark。我才刚刚开始对此进行修改,但正如我所解释的那样,虽然它的很大一部分功能来自多台机器的分片工作,但它即使在单台机器上也提供了并行执行模式。在设计方面,它似乎是“类固醇流”的东西,如果您的数据源允许,它似乎会变得懒惰。我将自己进一步追求这一点,所以我也会对任何更新感兴趣!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      • 2013-06-15
      相关资源
      最近更新 更多