bernardo.g
bernardo.g

Reputation: 748

Suspending IO-bound and CPU-bound functions in Kotlin's coroutines

Executing an IO-bound function (say, requesting data from a backend) in a coroutine gives me the advantage of suspending it's execution until the result of the request becomes available, right? However, a CPU-bound function (parsing a huge text file, for example) doesn't 'wait' for anything, it just does a lot of work. So, does executing it inside a coroutine NOT give me the advantage of suspending its execution? The only (valuable) advantage coroutines give me when it comes to CPU-bound functions is being able to choose the thread (or pool of threads) that will be blocked while executing the function, am I correct?

Upvotes: 2

Views: 912

Answers (2)

Joffrey
Joffrey

Reputation: 37720

So, does executing it inside a coroutine NOT give me the advantage of suspending its execution?

I am not sure I understand what you mean by that, but calling a suspending function will suspend the calling coroutine anyway, whatever dispatcher you choose, and that doesn't depend on what's inside the function as far as I know.

However, please note that calling a blocking function from inside a coroutine will make this coroutine block the thread executing it, there is no magic here. That's why blocking operations should be avoided inside coroutines.

The only (valuable) advantage coroutines give me when it comes to CPU-bound functions is being able to choose the thread (or pool of threads) that will be blocked while executing the function, am I correct?

Using Dispachers.IO or Dispatchers.Default only has the effect of choosing a different pool of threads, yes.

In case of IO, the pool will spawn as many threads as necessary, because they can all be "blocked on I/O".

In case of Default, only a number of threads proportional to the number of cores will ever be created, because there would be no point for CPU-bound tasks to create more threads than cores (if all the cores are busy, then context switching can only degrade the overall performance).

Upvotes: 2

Vairavan
Vairavan

Reputation: 1294

suspend functions do not automatically make the function as not blocking the thread, like in the following case as it would still block the calling thread ( dispatcher associated with the scope used to launch the coroutine)

suspend fun findBigPrime(): BigInteger = 
    BigInteger.probablePrime(4096, Random())

suspend functions can be made into a non-blocking thread function by using withContext like the following,

suspend fun findBigPrime(): BigInteger =
    withContext(Dispatchers.Default) {
        BigInteger.probablePrime(4096, Random())
    }

This causes coroutine launched from main/caller thread to be blocking but not the thread itself to be blocking.

https://medium.com/@elizarov/blocking-threads-suspending-coroutines-d33e11bf4761

Upvotes: 2

Related Questions