Esiste un modo semplice per utilizzare le collezioni parallele scala senza caricare una raccolta completa in memoria?Elaborazione parallela di raccolta di dati di dimensioni superiori alla memoria
Ad esempio, ho una grande collezione e mi piacerebbe eseguire una particolare operazione (fold) in parallelo solo su un piccolo blocco, che si adatta alla memoria, che su un altro blocco e così via, e infine ricombinare i risultati di tutti i pezzi
So che gli attori potrebbero essere utilizzati, ma sarebbe davvero bello usare le raccolte par.
ho scritto una soluzione, ma non è bello:
def split[A](list: Iterable[A], chunkSize: Int): Iterable[Iterable[A]] = {
new Iterator[Iterable[A]] {
var rest = list
def hasNext = !rest.isEmpty
def next = {
val chunk = rest.take(chunkSize)
rest = rest.drop(chunkSize)
chunk
}
}.toIterable
}
def foldPar[A](acc: A)(list: Iterable[A], chunkSize: Int, combine: ((A, A) => A)): A = {
val chunks: Iterable[Iterable[A]] = split(list, chunkSize)
def combineChunk: ((A,Iterable[A]) => A) = { case (res, entries) => entries.par.fold(res)(combine) }
chunks.foldLeft(acc)(combineChunk)
}
val chunkSize = 10000000
val x = 1 to chunkSize*10
def sum: ((Int,Int) => Int) = {case (acc,n) => acc + n }
foldPar(0)(x,chunkSize,sum)
direi che corretto modello di calcolo qui sarà * * map ridurre (e quindi potrebbe essere [Spark] (http://spark-project.org/examples/)), non gli attori di per sé. –
Formalmente - sì, ma il tempo di elaborazione non è sensato in questo caso quindi è del tutto normale eseguire su una singola macchina. –