Я пытаюсь использовать параллельное программирование в Scala. Основанный на this example здесь, в StackOverflow, я сделал программу на основе Problem 1 Project Euler. Я пробую три метода: первый - это простое исполнение, без паралилизма. В поле second используется API java.util.concurrency через исполнителей и вызываемые вызовы. Третий, основанный на странице, упомянутой выше, с использованием scala.Futures. Моя цель - сравнить время выполнения.Параллельная обработка в Scala
Это код:
package sandbox
import java.util.concurrent._
import scala.actors._
object TestPool {
def eval(n: Int): Boolean = (n % 3 == 0) || (n % 5 == 0)
def runSingle(max: Int): Int = (1 until max).filter(eval(_)).foldLeft(0)(_ + _)
def runPool(max: Int): Int = {
def getCallable(i: Int): Callable[Boolean] = new Callable[Boolean] { def call = eval(i) }
val pool = Executors.newFixedThreadPool(5)
val result = (1 until max).filter(i => pool.submit(getCallable(i)).get).foldLeft(0)(_ + _)
pool.shutdown
pool.awaitTermination(Math.MAX_LONG, TimeUnit.SECONDS)
result
}
def runFutures(max: Int): Int = (1 until max).filter(i => Futures.future(eval(i)).apply).foldLeft(0)(_ + _)
/**
* f is the function to be runned. it returns a Tuple2 containing the sum and the
* execution time.
*/
def test(max: Int, f: Int => Int): (Int, Long) = {
val t0 = System.currentTimeMillis
val result = f(max)
val deltaT = System.currentTimeMillis - t0
(result, deltaT)
}
def main(args : Array[String]) : Unit = {
val max = 10000
println("Single : " + test(max, runSingle))
println("Pool : " + test(max, runPool))
println("Futures: " + test(max, runFutures))
}
}
Таковы результаты:
макс = 10:
- Одно: (23,31)
- бассейн: (23, 16)
- Фьючерсы: (23,31)
макс = 100:
- Одно: (2318,33)
- бассейн: (2318,31)
- фьючерсы: (2318,55)
макс = 1000:
- Single: (233168,42)
- бассейн: (233168 , 111)
- Фьючерсные: (233168,364)
макс = 10000:
- Одно: (23331668,144)
- бассейн: (23331668,544)
- фьючерсы : ... Я отменил выполнение через 3 минуты
Очевидно, что я не мог использовать API параллелизма из Java и Scala правильно. Поэтому я спрашиваю: Где моя ошибка? Какова более подходящая форма использования параллелизма? А о Scala Актеры? Можно ли их использовать?