В чем преимущество использования фьючерсов над параллельными коллекциями в scala?
Есть ли веская причина для дополнительной сложности фьючерсов (против параллельных коллекций) при параллельной обработке списка элементов?
List(...).par.foreach(x=>longRunningAction(x))
против
Future.traverse(List(...)) (x=>Future(longRunningAction(x)))
Ответы
Ответ 1
Я думаю, что основным преимуществом будет то, что вы можете получить доступ к результатам каждого будущего, как только он будет вычислен, в то время как вам придется ждать, пока все вычисления будут выполнены с помощью параллельной коллекции. Недостатком может быть то, что вы в конечном итоге создаете много фьючерсов. Если вы позже в конечном итоге вызываете Future.sequence, на самом деле нет никакого преимущества.
Ответ 2
Фьючерсы становятся полезными, как только вы хотите составить свои отложенные/параллельные вычисления. Фьючерсы (хороший, во всяком случае, такие как Akka's) являются монадическими и, следовательно, позволяют создавать произвольно сложные вычислительные структуры со всеми concurrency и синхронизацией, правильно обработанными библиотекой Futures.
Ответ 3
Параллельные коллекции убьют некоторые потоки, поскольку мы приближаемся к обработке всех элементов. Таким образом, последние несколько элементов могут быть обработаны одним потоком. Пожалуйста, смотрите мой вопрос для получения более подробной информации об этом поведении. Использование ThreadPoolTaskSupport в качестве поддержки задач для параллельных коллекций в Scala
Будущее не делает такой вещи, и все ваши потоки используются, пока все объекты не будут обработаны. Следовательно, если ваши задачи не настолько малы, что вас не волнует потеря параллелизма для последних нескольких задач, и вы используете огромное количество потоков, которые должны быть уничтожены как можно скорее, Futures лучше.