Launch coroutine builder in Kotlin - Time & Space Complexity
When we use the launch coroutine builder in Kotlin, it starts a new task that runs alongside other code.
We want to understand how the time it takes to start and run these tasks changes as we start more of them.
Analyze the time complexity of the following code snippet.
import kotlinx.coroutines.*
fun main() = runBlocking {
repeat(5) { i ->
launch {
println("Task $i running")
delay(100L)
}
}
}
This code starts 5 coroutines that each print a message and wait briefly.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The
repeat(5)loop that launches 5 coroutines. - How many times: Exactly 5 times, once per coroutine started.
As the number of coroutines started increases, the total number of launch operations grows directly with it.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 launches |
| 100 | 100 launches |
| 1000 | 1000 launches |
Pattern observation: The work grows in a straight line as you add more coroutines.
Time Complexity: O(n)
This means the time to start all coroutines grows directly with the number of coroutines you launch.
[X] Wrong: "Starting many coroutines happens instantly and does not add up."
[OK] Correct: Each coroutine launch takes some time, so starting more coroutines adds more work overall.
Understanding how launching many coroutines affects performance helps you write responsive and efficient Kotlin programs.
"What if we replaced launch with async? How would the time complexity change?"
Practice
launch coroutine builder do in Kotlin?Solution
Step 1: Understand the purpose of
Thelaunchlaunchbuilder starts a coroutine that runs concurrently without blocking the current thread.Step 2: Compare with other coroutine builders
Unlikeasync,launchdoes not return a result and does not block the thread.Final Answer:
Starts a new coroutine that runs independently without blocking the current thread. -> Option AQuick Check:
launch= independent coroutine start [OK]
- Thinking launch blocks the thread
- Expecting launch to return a value
- Confusing launch with thread creation
Solution
Step 1: Recall the syntax of
Thelaunchlaunchbuilder requires a lambda block enclosed in curly braces.Step 2: Check each option
launch { println("Hello") } correctly useslaunch { ... }. Others have syntax errors or wrong symbols.Final Answer:
launch { println("Hello") } -> Option BQuick Check:
Correct coroutine launch syntax = launch { println("Hello") } [OK]
- Omitting curly braces
- Using parentheses without braces
- Using arrow or colon incorrectly
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(100)
println("World")
}
println("Hello")
}Solution
Step 1: Analyze the order of execution
Thelaunchcoroutine delays 100ms before printing "World". Meanwhile,println("Hello")runs immediately.Step 2: Understand runBlocking behavior
runBlockingwaits for all child coroutines to complete before exiting, so both prints occur.Final Answer:
Hello World -> Option CQuick Check:
Immediate print then delayed print = Hello\nWorld [OK]
- Assuming launch blocks main thread
- Expecting 'World' before 'Hello'
- Ignoring delay effect
fun main() = runBlocking {
launch {
delay(100)
println("Done")
}
cancel()
println("Cancelled")
}Solution
Step 1: Understand cancel() effect on runBlocking
Callingcancel()cancels the entire coroutine scope immediately, stopping child coroutines.Step 2: Check output consequences
Because of cancellation, the launched coroutine does not complete, so "Done" is not printed, but "Cancelled" is printed after cancel.Final Answer:
Calling cancel() cancels the runBlocking scope immediately, so "Done" is never printed. -> Option DQuick Check:
cancel() stops coroutines immediately = Calling cancel() cancels the runBlocking scope immediately, so "Done" is never printed. [OK]
- Thinking delay() is invalid in launch
- Expecting launch to return a value
- Assuming println after cancel won't run
Solution
Step 1: Ensure main waits for coroutines
UsingrunBlockingwithlaunchinside ensures the main thread waits for all launched coroutines to complete.Step 2: Check each option's behavior
runBlocking { repeat(3) { i -> launch { delay(100L * i) println(i + 1) } } } launches coroutines insiderunBlocking, so main waits. runBlocking { repeat(3) { i -> launch { delay(100L * i) println(i + 1) } } println("Done") } prints "Done" immediately without waiting. repeat(3) { i -> launch { delay(100L * i) println(i + 1) } } println("Done") launches outside runBlocking, so main exits early. runBlocking { repeat(3) { i -> launch { delay(100L * i) println(i + 1) } } delay(400) } uses delay but is less reliable than waiting for coroutines.Final Answer:
runBlocking with launch inside to wait for all coroutines. -> Option AQuick Check:
runBlocking + launch inside = wait for all [OK]
- Launching coroutines outside runBlocking
- Printing before coroutines finish
- Using delay to wait instead of structured concurrency
Ready to prove it?
Pass the test and this pattern moves unknown
