Buscar..


Observaciones

Las colecciones paralelas facilitan la programación paralela al ocultar los detalles de paralelización de bajo nivel. Esto hace que tomar ventaja de las arquitecturas de múltiples núcleos sea fácil. Los ejemplos de colecciones paralelas incluyen ParArray , ParVector , mutable.ParHashMap , immutable.ParHashMap y ParRange . Una lista completa se puede encontrar en la documentación .

Creación y uso de colecciones paralelas

Para crear una colección paralela a partir de una colección secuencial, llame al método par . Para crear una colección secuencial a partir de una colección paralela, llame al método seq . Este ejemplo muestra cómo convertir un Vector regular en un ParVector y luego de nuevo:

scala> val vect = (1 to 5).toVector
vect: Vector[Int] = Vector(1, 2, 3, 4, 5)

scala> val parVect = vect.par
parVect: scala.collection.parallel.immutable.ParVector[Int] = ParVector(1, 2, 3, 4, 5)

scala> parVect.seq
res0: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3, 4, 5)

El método par se puede encadenar, lo que le permite convertir una colección secuencial en una colección paralela y realizar una acción de inmediato:

scala> vect.map(_ * 2)
res1: scala.collection.immutable.Vector[Int] = Vector(2, 4, 6, 8, 10)

scala> vect.par.map(_ * 2)
res2: scala.collection.parallel.immutable.ParVector[Int] = ParVector(2, 4, 6, 8, 10)

En estos ejemplos, el trabajo en realidad se divide en varias unidades de procesamiento y luego se vuelve a unir después de que el trabajo se completa, sin la intervención del desarrollador.

Escollos

No utilice colecciones paralelas cuando los elementos de la colección deben recibirse en un orden específico.

Las colecciones paralelas realizan operaciones concurrentemente. Eso significa que todo el trabajo se divide en partes y se distribuye a diferentes procesadores. Cada procesador desconoce el trabajo realizado por otros. Si el orden de la colección importa, entonces el trabajo procesado en paralelo no es determinista. (Ejecutar el mismo código dos veces puede producir resultados diferentes).


Operaciones no asociativas

Si una operación no es asociativa (si el orden de ejecución es importante), el resultado en una recopilación en paralelo no será determinista.

scala> val list = (1 to 1000).toList
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...

scala> list.reduce(_ - _)
res0: Int = -500498

scala> list.reduce(_ - _)
res1: Int = -500498

scala> list.reduce(_ - _)
res2: Int = -500498

scala> val listPar = list.par
listPar: scala.collection.parallel.immutable.ParSeq[Int] = ParVector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...

scala> listPar.reduce(_ - _)
res3: Int = -408314

scala> listPar.reduce(_ - _)
res4: Int = -422884

scala> listPar.reduce(_ - _)
res5: Int = -301748

Efectos secundarios

Las operaciones que tienen efectos secundarios, como foreach , pueden no ejecutarse como se desea en colecciones en paralelo debido a las condiciones de la carrera. Evite esto utilizando funciones que no tengan efectos secundarios, como reduce o map .

scala> val wittyOneLiner = Array("Artificial", "Intelligence", "is", "no", "match", "for", "natural", "stupidity")

scala> wittyOneLiner.foreach(word => print(word + " "))
Artificial Intelligence is no match for natural stupidity 

scala> wittyOneLiner.par.foreach(word => print(word + " "))
match natural is for Artificial no stupidity Intelligence

scala> print(wittyOneLiner.par.reduce{_ + " " + _})
Artificial Intelligence is no match for natural stupidity

scala> val list = (1 to 100).toList
list: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15...


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow