Поиск…


замечания

Параллельные коллекции облегчают параллельное программирование, скрывая детали параллелизма низкого уровня. Это упрощает использование многоядерных архитектур. Примеры параллельных коллекций включают ParArray , ParVector , mutable.ParHashMap , immutable.ParHashMap и ParRange . Полный список можно найти в документации .

Создание и использование параллельных коллекций

Чтобы создать параллельную коллекцию из последовательной коллекции, вызовите метод par . Чтобы создать последовательный сбор из параллельной коллекции, вызовите метод seq . В этом примере показано, как вы превращаете обычный Vector в ParVector , а затем снова:

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)

Метод par может быть привязан, что позволяет конвертировать последовательную коллекцию в параллельную коллекцию и немедленно выполнять действие над ней:

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)

В этих примерах работа фактически распределяется по нескольким модулям обработки, а затем снова объединяется после завершения работы без вмешательства разработчика.

Ловушки

Не используйте параллельные коллекции, когда элементы коллекции должны быть получены в определенном порядке.

Параллельные коллекции выполняют операции одновременно. Это означает, что вся работа делится на части и распространяется на разные процессоры. Каждый процессор не знает о работе, выполняемой другими. Если порядок сбора имеет значение, то работа, обрабатываемая параллельно, недетерминирована. (Выполнение того же кода дважды может дать разные результаты.)


Неассоциативные операции

Если операция неассоциативна (если порядок выполнения имеет значение), то результат в распараллеленном наборе будет недетерминированным.

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

Побочные эффекты

Операции, которые имеют побочные эффекты, такие как foreach , могут не выполняться по желанию при параллельных сборах из-за условий гонки. Избегайте этого, используя функции, которые не имеют побочных эффектов, таких как reduce или 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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow