#scala #parallel-processing
#scala #параллельная обработка
Вопрос:
Я получаю противоречивые ответы из следующего кода, который я нахожу странным.
import scala.math.pow
val p = 2
val a = Array(1,2,3)
println(a.par
.aggregate("0")((x, y) => s"$y pow $p; ", (x, y) => x y))
for (i <- 1 to 100) {
println(a.par
.aggregate(0.0)((x, y) => pow(y, p), (x, y) => x y) == 14)
}
a.map(x => pow(x,p)).sum
В коде a.par ...
вычисляется 14
или 10
. Может ли кто-нибудь объяснить, почему он вычисляет непоследовательно?
Ответ №1:
В вашей функции «seqop», которая является первой функцией, к которой вы переходите aggregate
, вы определяете логику, которая используется для объединения элементов в одном разделе. Ваша функция выглядит следующим образом:
(x, y) => pow(y, p)
Проблема в том, что вы не накапливаете результаты раздела. Вместо этого вы выбрасываете свой аккумулятор x
. Каждый раз, когда вы получаете 10 в результате, вычисление 2^2
отбрасывалось.
Если вы измените свою функцию, чтобы учитывать накопленное значение, вы будете получать 14 каждый раз:
(x, y) => x pow(y, p)
Ответ №2:
Правильный способ использования aggregate
a.par.aggregate(0.0)(
(acc, value) => acc pow(value, 2), (acc1, acc2) => acc1 acc2
)
Используя (x, y) => pow(y,2) , вы не накапливали элемент в накопителе, а просто заменяли накопитель на pow(y,2) .