Coroutines vs threads mental model in Kotlin - Performance Comparison
When working with coroutines and threads in Kotlin, it is important to understand how their execution costs grow as we increase workload.
We want to see how the time taken changes when we run many tasks using coroutines versus threads.
Analyze the time complexity of launching multiple tasks using threads and coroutines.
fun runThreads(n: Int) {
repeat(n) {
Thread {
// some work
}.start()
}
}
suspend fun runCoroutines(n: Int) {
repeat(n) {
kotlinx.coroutines.GlobalScope.launch {
// some work
}
}
}
This code runs n tasks either by creating n threads or launching n coroutines.
Look at what repeats as input size grows.
- Primary operation: Creating and running
ntasks (threads or coroutines). - How many times: Exactly
ntimes, once per task.
As we increase n, the number of tasks grows linearly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 tasks created and run |
| 100 | 100 tasks created and run |
| 1000 | 1000 tasks created and run |
Pattern observation: The work grows directly with the number of tasks.
Time Complexity: O(n)
This means the time to start and run all tasks grows in a straight line as we add more tasks.
[X] Wrong: "Coroutines always run faster than threads because they are lightweight."
[OK] Correct: While coroutines use fewer resources, the total time depends on the work done and how tasks are scheduled, not just on their lightweight nature.
Understanding how coroutines and threads scale helps you explain efficient multitasking in Kotlin, a skill useful in many programming situations.
What if we changed the tasks to do heavy CPU work instead of light work? How would the time complexity change?