2016-11-20 60 views
3

有沒有什麼辦法可以在scala中並行運行流而不需要將所有對象加載到內存中?scala懶惰的平行集合(是可能的?)

注:使用參數的方法,將所有對象加載到內存中

val list = "a"::"b"::"c"::"d"::"e"::Nil //> list: List[String] = List(a, b, c, d, e) 

val s = list.toStream //> s: scala.collection.immutable.Stream[String] = Stream(a, ?) 
val sq = s.par   //> sq: scala.collection.parallel.immutable.ParSeq[String] = ParVector(a, b, c, d, e) 
sq.map { x => println("Map 1 "+x);x } 
    .map { x => println("Map 2 "+x);x} 
    .map { x => println("Map 3 "+x);x } 
    .foreach { x => println("done "+x)} 
+4

聽起來不可能的:「其他收藏品,如列表,隊列或流,本質上是連續的,因爲元素必須一個接一個地訪問。這些集合通過將元素_複製到類似的並行集合中轉換爲它們的平行變體「http://docs.scala-lang.org/overviews/parallel-collections/conversions.html –

+0

你的問題相當含糊,一個低於這個答案的答案可以回答問題,但我懷疑你有一個更具體的用例,如果你問一個更具體的問題,你可能會得到更好的答案。 – Rich

回答

0

在一般情況下,是的,這是可能的。

作爲Tzach Zohar的評論中,「.PAR」操作者將急切地加載,因爲‘流是在這個意義上固有地順序元件必須被訪問一個在另一個之後的’信息流中的所有元素(見the docs

所以你不能使用內置的這種並行的集合,但你仍然可以使用ExecutionContext直接,例如並行處理流:

import scala.concurrent._ 
import scala.concurrent.duration.Duration 
import scala.concurrent.ExecutionContext.Implicits.global 

val infStream = Stream.from(1) 

val mappedInfStream = infStream 
    .map { x => Future(println(s"processing $x on ${Thread.currentThread.getName}")) } 

Await.result(
    Future.sequence(mappedInfStream.take(100)), 
    Duration.Inf)