Scala Language
병렬 컬렉션
수색…
비고
병렬 컬렉션은 낮은 수준의 병렬화 세부 정보를 숨김으로써 병렬 프로그래밍을 용이하게합니다. 따라서 멀티 코어 아키텍처를 쉽게 활용할 수 있습니다. 병렬 컬렉션의 예로 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
과 같은 부작용이없는 함수를 사용하면이 문제를 피할 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...