Скала аналоги QtConcurrent - PullRequest
       5

Скала аналоги QtConcurrent

10 голосов
/ 18 сентября 2010

Какие есть аналоги QtConcurrent для Scala (или Java)?Т.е. упрощенная реализация MapReduce, параллельная карта и сложение.Спасибо

Ответы [ 3 ]

12 голосов
/ 21 сентября 2010

Вы можете использовать Scala Parallel Collections.В настоящее время они являются частью ночных выпусков Scala и будут выпущены в Scala 2.9.Идея состоит в том, что большинство операций, доступных в обычных коллекциях, распараллеливаются, поэтому параллельные коллекции могут использоваться одинаково.

В настоящее время доступно несколько типов коллекций - параллельные диапазоны, параллельные массивы и параллельные хэши.,Например, вы можете вызывать параллельные операции map и fold для параллельного массива следующим образом:

scala> val pa = (0 until 10000).toArray.par
pa: scala.collection.parallel.mutable.ParArray[Int] = ParArray(0, 1, 2, 3, 4, 5, 6,...

scala> pa.map(_ + 1)
res0: scala.collection.parallel.mutable.ParArray[Int] = ParArray(1, 2, 3, 4, 5, 6, 7,...

scala> pa map { v => if (v % 2 == 0) v else -v }
res1: scala.collection.parallel.mutable.ParArray[Int] = ParArray(0, -1, 2, -3, 4, -5,...

scala> pa.fold(0) { _ + _ }
res2: Int = 49995000

Также доступны другие операции параллельного сбора.Обратите внимание, что fold должен принимать ассоциативный оператор - в приведенном выше примере сложение является ассоциативным ((A + B) + C == A + (B + C)), т.е. вы можете добавлять подпоследовательности чисел в любом порядке, и вывсегда получит одинаковую сумму (reduce имеет аналогичный контракт).

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

scala> var a = 0                                                                                                                                                                 
a: Int = 0                                                                                                                                                                       

scala> pa foreach { a += _ }                                                                                                                                                     

scala> a                                                                                                                                                                         
res1: Int = 49995000             

scala> a = 0
a: Int = 0

scala> pa foreach { a += _ }

scala> a
res7: Int = 49990086

и каждый раз получать разные результаты, потому что foreach вызывает { a += _ } параллельно.В приведенном выше примере a должен быть синхронизирован, защищен блокировкой или атомарностью.

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

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

7 голосов
/ 18 сентября 2010

См. Scala Parallel Collections видео и статья " Общая структура параллельной коллекции "

В этом состоянии : параллельные коллекции находятся в текущих сборках разработки и будут выпущены как часть Scala 2.9. См. План выпуска здесь , Scala 2.9 можно загрузить здесь .

3 голосов
/ 18 сентября 2010

Вы можете пройти долгий путь, используя scala.actors.Futures и обычные map / flatMap над коллекциями. Однако не легко распараллелить fold.

Если вы используете несколько хостов, я бы использовал Akka send-and-receive-future.

...