Czy istnieje prosty sposób wykorzystania równoległych kolekcji scala bez załadowania pełnej kolekcji do pamięci?Równoległe przetwarzanie danych większych niż rozmiar pamięci
Na przykład mam dużą kolekcję i chciałbym wykonać określoną operację (zwijanie) równolegle tylko na małej porcji, która mieści się w pamięci, niż na innym kawałku itd., A na końcu rekombinować wyniki z wszystkie kawałki.
Wiem, że aktorzy mogą być wykorzystywani, ale byłoby naprawdę miło korzystać z par-kolekcji.
Pisałem rozwiązanie, ale nie jest to miłe:
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)
Powiedziałbym, że poprawny model obliczeniowy tutaj będzie * mapa zredukować * (a więc może to być [Spark] (http://spark-project.org/examples/)), a nie aktorzy per se. –
Formalnie - tak, ale czas przetwarzania nie jest rozsądny w tym przypadku, więc można całkowicie uruchomić na jednej maszynie. –