Suddenly discover that recursive call of suspend function takes more time then calling the same function but without suspend
modifier, so please consider the code snippet below (basic Fibonacci series calculation):
suspend fun asyncFibonacci(n: Int): Long = when {
n <= -2 -> asyncFibonacci(n + 2) - asyncFibonacci(n + 1)
n == -1 -> 1
n == 0 -> 0
n == 1 -> 1
n >= 2 -> asyncFibonacci(n - 1) + asyncFibonacci(n - 2)
else -> throw IllegalArgumentException()
}
If I call this function and measure its execution time with code below:
fun main(args: Array<String>) {
val totalElapsedTime = measureTimeMillis {
val nFibonacci = 40
val deferredFirstResult: Deferred<Long> = async {
asyncProfile("fibonacci") { asyncFibonacci(nFibonacci) } as Long
}
val deferredSecondResult: Deferred<Long> = async {
asyncProfile("fibonacci") { asyncFibonacci(nFibonacci) } as Long
}
val firstResult: Long = runBlocking { deferredFirstResult.await() }
val secondResult: Long = runBlocking { deferredSecondResult.await() }
val superSum = secondResult + firstResult
println("${thread()} - Sum of two $nFibonacci'th fibonacci numbers: $superSum")
}
println("${thread()} - Total elapsed time: $totalElapsedTime millis")
}
I observe further results:
commonPool-worker-2:fibonacci - Start calculation...
commonPool-worker-1:fibonacci - Start calculation...
commonPool-worker-2:fibonacci - Finish calculation...
commonPool-worker-2:fibonacci - Elapsed time: 7704 millis
commonPool-worker-1:fibonacci - Finish calculation...
commonPool-worker-1:fibonacci - Elapsed time: 7741 millis
main - Sum of two 40'th fibonacci numbers: 204668310
main - Total elapsed time: 7816 millis
But if I remove suspend
modifier from asyncFibonacci
function, I'll have this result:
commonPool-worker-2:fibonacci - Start calculation...
commonPool-worker-1:fibonacci - Start calculation...
commonPool-worker-1:fibonacci - Finish calculation...
commonPool-worker-1:fibonacci - Elapsed time: 1179 millis
commonPool-worker-2:fibonacci - Finish calculation...
commonPool-worker-2:fibonacci - Elapsed time: 1201 millis
main - Sum of two 40'th fibonacci numbers: 204668310
main - Total elapsed time: 1250 millis
I know that's better to rewrite such a function with tailrec
it will increase its execution time apx. almost in 100 times, but anyway, what this suspend
key word does that decrease execution speed from 1 second to 8 seconds?
Is it totally stupid idea to mark recursive functions with suspend
?
asyncProfile
. – Dinothere