Coroutine scope and structured concurrency in Kotlin - Time & Space Complexity
We want to understand how the time cost grows when using coroutine scopes and structured concurrency in Kotlin.
Specifically, how launching and managing coroutines affects the total work done as input size changes.
Analyze the time complexity of the following code snippet.
fun fetchAllData(ids: List<Int>) = runBlocking {
ids.forEach { id ->
launch {
fetchData(id) // suspending function
}
}
}
suspend fun fetchData(id: Int) {
delay(100) // simulate network call
}
This code launches one coroutine per id to fetch data concurrently inside a coroutine scope.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Launching a coroutine for each id in the list.
- How many times: Once per element in the input list (n times).
Each id causes one coroutine to start, so the total number of coroutines grows linearly with input size.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 coroutines launched |
| 100 | 100 coroutines launched |
| 1000 | 1000 coroutines launched |
Pattern observation: The work grows directly in proportion to the number of input items.
Time Complexity: O(n)
This means the total time grows linearly as you add more items to process concurrently.
[X] Wrong: "Launching many coroutines means the program runs instantly regardless of input size."
[OK] Correct: Even though coroutines run concurrently, each one still does work, so total time and resource use grow with the number of coroutines.
Understanding how coroutine scopes manage concurrent tasks helps you explain how programs handle many jobs at once without losing control.
"What if we changed launch to async and awaited all results? How would the time complexity change?"