I'm reading Akka cookbook
and found it interesting to improve the function performance in one sample.
I have the next client object:
object HelloAkkaActorSystem extends App {
implicit val timeout = Timeout(50 seconds)
val actorSystem = ActorSystem("HelloAkka")
val actor = actorSystem.actorOf(Props[FibonacciActor])
// asking for result from actor
val future = (actor ? 6).mapTo[Int]
val st = System.nanoTime()
val fiboacciNumber = Await.result(future, 60 seconds)
println("Elapsed time: " + (System.nanoTime() - st) / math.pow(10, 6))
println(fiboacciNumber)
}
And two implementations of actor class.
First:
class FibonacciActor extends Actor {
override def receive: Receive = {
case num : Int =>
val fibonacciNumber = fib(num)
sender ! fibonacciNumber
}
def fib( n : Int) : Int = n match {
case 0 | 1 => n
case _ => fib( n-1 ) + fib( n-2 )
}
}
Second:
class FibonacciActor extends Actor {
override def receive: PartialFunction[Any, Unit] = {
case num : Int =>
val fibonacciNumber = fib(num)
val s = sender()
fibonacciNumber.onComplete {
case Success(x) => s ! x
case Failure(e) => s ! -1
}
}
def fib( n : Int) : Future[Int] = n match {
case 0 | 1 => Future{ n }
case _ =>
fib( n-1 ).flatMap(n_1 =>
fib( n-2 ).map(n_2 =>
n_1 + n_2))
}
}
At my machine First
variant executed in 0.12 ms, Second
in 360 ms. So the Second
is 300 times slower. Using htop
I found that First
variant use 1 core against all 4 in second case.
Is it so because too many async tasks generated? And how to speed up fib(n: Int)
method?