Есть ли реализация быстрого одновременного синтаксического сахара в скале? например. уменьшение карты - PullRequest
4 голосов
/ 28 апреля 2010

Передача сообщений с актерами это здорово. Но я хотел бы иметь еще более простой код.

Примеры (псевдокод)

val splicedList:List[List[Int]]=biglist.partition(100)
val sum:Int=ActorPool.numberOfActors(5).getAllResults(splicedList,foldLeft(_+_))

где spliceIntoParts превращает один большой список в 100 маленьких списков часть numberofactors создает пул, который использует 5 актеров и получает новые задания после завершения задания и getallresults использует метод в списке. все это сделано с сообщениями, проходящими в фоновом режиме. где, возможно, getFirstResult, вычисляет первый результат и останавливает все остальные потоки (например, взлом пароля)

Ответы [ 5 ]

4 голосов
/ 29 апреля 2010

С коллекциями Scala Parallel, которые будут включены в 2.8.1, вы сможете делать такие вещи:

val spliced = myList.par // obtain a parallel version of your collection (all operations are parallel)
spliced.map(process _)   // maps each entry into a corresponding entry using `process`
spliced.find(check _)    // searches the collection until it finds an element for which
                         // `check` returns true, at which point the search stops, and the element is returned

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

В настоящее время 2.8.RC2 очень близок (на этой или следующей неделе), и финал 2.8 состоится через несколько недель, я думаю Вы сможете попробовать параллельные коллекции, если будете использовать 2.8.1 nightlies.

3 голосов
/ 28 апреля 2010

Вы можете использовать функции параллелизма Scalaz для достижения желаемого.

import scalaz._
import Scalaz._
import concurrent.strategy.Executor
import java.util.concurrent.Executors

implicit val s = Executor.strategy[Unit](Executors.newFixedThreadPool(5))

val splicedList = biglist.grouped(100).toList
val sum = splicedList.parMap(_.sum).map(_.sum).get

Было бы довольно легко сделать это красивее (то есть написать функцию mapReduce, которая выполняет разбиение и сворачивание всего в одном). Кроме того, parMap над списком излишне строг. Вы захотите начать сворачивание до того, как весь список будет готов. Больше похоже на:

val splicedList = biglist.grouped(100).toList
val sum = splicedList.map(promise(_.sum)).toStream.traverse(_.sum).get
2 голосов
/ 29 апреля 2010

Я не жду Scala 2.8.1 или 2.9, лучше было бы написать свою собственную библиотеку или использовать другую, поэтому я сделал больше поисков в Google и нашел это: http://doc.akkasource.org/actors

, у которого есть объект фьючерсы с методами

awaitAll(futures: List[Future]): Unit
awaitOne(futures: List[Future]): Future

но http://scalablesolutions.se/akka/api/akka-core-0.8.1/ не имеет документации вообще. Это плохо.

Но хорошая сторона в том, что актеры Акки стройнее, чем актеры Скалы
При наличии всех этих библиотек (включая scalaz) было бы здорово, если бы сама scala могла в конечном итоге объединить их официально

2 голосов
/ 28 апреля 2010

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

import scala.actors.Futures._
val nums = (1 to 1000).grouped(100).toList
val parts = nums.map(n => future { n.reduceLeft(_ + _) })
val whole = (0 /: parts)(_ + _())

Вы должны справиться с разложением проблемы и записью блока "future" и перекомпоновкой его в окончательный ответ, но это облегчает выполнение множества небольших блоков кода параллельно.

(Обратите внимание, что _() в левой части окна - это функция применения будущего, которая означает «Дайте мне ответ, который вы рассчитывали параллельно!», И блокируется, пока ответ не станет доступен.)

Библиотека параллельных коллекций автоматически разложит проблему и предложит вам ответ (как в pmap в Clojure); это еще не часть основного API.

1 голос
/ 28 апреля 2010

На Scala Days 2010 была очень интересная беседа Александара Прокопека (который работает над Scala в EPFL) о Parallel Collections . Это, вероятно, будет в 2.8.1, но вам, возможно, придется подождать немного дольше. Я посмотрю, смогу ли я получить презентацию сама. для ссылки здесь.

Идея состоит в том, чтобы иметь структуру коллекций, которая распараллеливает обработку коллекций, выполняя то, что вы предлагаете, но прозрачно для пользователя. Все, что вам теоретически нужно сделать, это изменить импорт с scala.collections на scala.parallel.collections. Очевидно, вам все еще нужно выполнить работу, чтобы понять, можно ли распараллелить то, что вы делаете, на самом деле.

...