Bird
Raised Fist0
Kotlinprogramming~5 mins

Async and await for concurrent results in Kotlin - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Async and await for concurrent results
O(1)
Understanding Time Complexity

When using async and await in Kotlin, we want to know how the program's running time changes as we add more tasks to run at the same time.

We ask: How does running many tasks concurrently affect the total time?

Scenario Under Consideration

Analyze the time complexity of the following code snippet.

import kotlinx.coroutines.*

suspend fun fetchData(id: Int): String {
    delay(1000) // Simulate network delay
    return "Data $id"
}

suspend fun loadAllData(ids: List): List = coroutineScope {
    val deferredResults = ids.map { id -> async { fetchData(id) } }
    deferredResults.awaitAll()
}

This code fetches data for each id concurrently using async, then waits for all results.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: Launching async tasks for each id in the list.
  • How many times: Once per id, so as many times as the list size.
How Execution Grows With Input

Each fetchData call takes about the same time, but they run at the same time, not one after another.

Input Size (n)Approx. Operations
10About 1 second total (all 10 run together)
100About 1 second total (all 100 run together)
1000About 1 second total (all 1000 run together)

Pattern observation: Total time stays roughly the same as input grows, because tasks run concurrently.

Final Time Complexity

Time Complexity: O(1)

This means the total running time does not grow with the number of tasks because they run at the same time.

Common Mistake

[X] Wrong: "Running more async tasks always takes more total time."

[OK] Correct: Because async tasks run together, the total time depends on the longest single task, not the number of tasks.

Interview Connect

Understanding how async and await affect time helps you explain how to handle many tasks efficiently, a useful skill in real projects.

Self-Check

"What if fetchData tasks had different delays? How would that affect the total time complexity?"

Practice

(1/5)
1. What does the async function do in Kotlin coroutines?
easy
A. Starts a background task that runs concurrently
B. Waits for a task to complete and returns its result
C. Blocks the main thread until a task finishes
D. Cancels a running coroutine immediately

Solution

  1. Step 1: Understand the role of async

    async starts a coroutine that runs in the background without blocking the main thread.
  2. Step 2: Differentiate from await

    await waits for the result of the background task started by async, but async itself only starts the task.
  3. Final Answer:

    Starts a background task that runs concurrently -> Option A
  4. Quick Check:

    async = starts background task [OK]
Hint: Async starts tasks without waiting, await waits for results [OK]
Common Mistakes:
  • Confusing async with await
  • Thinking async blocks the main thread
  • Assuming async cancels tasks
2. Which of the following is the correct syntax to start two concurrent tasks and wait for both results in Kotlin?
easy
A. val result1 = async { task1() }.await() val result2 = async { task2() }.await()
B. val result1 = await(async { task1() }) val result2 = await(async { task2() })
C. val deferred1 = async { task1() } val deferred2 = async { task2() } val result1 = deferred1.await() val result2 = deferred2.await()
D. val result1 = task1() val result2 = task2()

Solution

  1. Step 1: Identify correct async-await usage

    In Kotlin, async returns a Deferred object, which you then call await() on to get the result.
  2. Step 2: Check syntax correctness

    val deferred1 = async { task1() } val deferred2 = async { task2() } val result1 = deferred1.await() val result2 = deferred2.await() correctly starts two async tasks and awaits their results separately, allowing concurrency.
  3. Final Answer:

    val deferred1 = async { task1() } val deferred2 = async { task2() } val result1 = deferred1.await() val result2 = deferred2.await() -> Option C
  4. Quick Check:

    async returns Deferred, await gets result [OK]
Hint: Store async in Deferred, then call await separately [OK]
Common Mistakes:
  • Calling await immediately after async (no concurrency)
  • Using await as a standalone function
  • Not storing async result before await
3. What will be the output of the following Kotlin code?
import kotlinx.coroutines.*

fun main() = runBlocking {
    val deferred1 = async {
        delay(100)
        10
    }
    val deferred2 = async {
        delay(50)
        20
    }
    println(deferred1.await() + deferred2.await())
}
medium
A. 10
B. 30
C. 20
D. Compilation error

Solution

  1. Step 1: Understand async and delay behavior

    Two async tasks run concurrently: one delays 100ms and returns 10, the other delays 50ms and returns 20.
  2. Step 2: Await both results and sum

    Awaiting both deferreds gets 10 and 20, summing to 30, printed as output.
  3. Final Answer:

    30 -> Option B
  4. Quick Check:

    10 + 20 = 30 [OK]
Hint: Sum awaited results after async tasks complete [OK]
Common Mistakes:
  • Assuming sequential execution ignoring concurrency
  • Confusing delay times with output values
  • Expecting compilation errors due to coroutines
4. Identify the error in this Kotlin coroutine code snippet:
fun main() = runBlocking {
    val result = async {
        delay(100)
        42
    }.await()
    println(result)
}
medium
A. Calling await() immediately after async() blocks concurrency
B. Missing coroutine scope for async
C. delay() cannot be used inside async
D. runBlocking cannot be used in main function

Solution

  1. Step 1: Analyze async and await usage

    Calling await() immediately after async waits for the task to finish before continuing, so concurrency is lost.
  2. Step 2: Understand concurrency impact

    This pattern runs the async task sequentially, blocking until completion, defeating the purpose of async concurrency.
  3. Final Answer:

    Calling await() immediately after async() blocks concurrency -> Option A
  4. Quick Check:

    Immediate await blocks concurrency [OK]
Hint: Don't await right after async; store Deferred first [OK]
Common Mistakes:
  • Thinking immediate await keeps concurrency
  • Believing delay is disallowed inside async
  • Assuming runBlocking can't be main
5. You want to fetch data from two APIs concurrently and combine their results in Kotlin. Which approach best uses async and await for this task?
hard
A. Call the first API synchronously, then start async for the second API and await it
B. Run both API calls sequentially inside async blocks without await
C. Use await without async for both API calls to simplify code
D. Start two async coroutines for each API call, then await both results before combining

Solution

  1. Step 1: Understand concurrency for API calls

    Starting both API calls concurrently with async allows them to run at the same time, saving time.
  2. Step 2: Await both results before combining

    Using await on both deferred results ensures you get both responses before combining them safely.
  3. Final Answer:

    Start two async coroutines for each API call, then await both results before combining -> Option D
  4. Quick Check:

    Async start + await both = concurrent fetch [OK]
Hint: Async both calls, await both results, then combine [OK]
Common Mistakes:
  • Running API calls sequentially losing concurrency
  • Using await without async causing errors
  • Not awaiting results before combining
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard