I am trying to use concurrent programming in Scala. Based on this example here StackOverflow, I made a program based on Problem 1 Project Euler. I try three methods: the first is simple execution, without paralysis. the second uses the java.util.concurrency API through Executors and Callables. The third, based on the page mentioned above, using Scala. Futures. My goal is to compare runtime.
This is the code:
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)(_ + _) 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)) } }
Here are the results:
max = 10:
- Single: (23.31)
- Pool: (23.16)
- Futures: (23.31)
max = 100:
- Single: (2318.33)
- Pool: (2318.31)
- Futures: (2318.55)
max = 1000:
- Single: (233,168.42)
- Pool: (233,168,111)
- Futures: (233,168,364)
max = 10000:
- Single: (23331668,144)
- Pool: (23331668,544)
- Futures: ... I canceled the performance after 3 minutes.
Obviously, I could not use the concurrency API from Java and Scala correctly. So I ask: Where is my mistake? What is a more suitable form of using Concurrency? What about Scala Actors? Is it possible to use them?
source share