Lazy evaluation vs eager evaluation in Kotlin - Performance Comparison
We want to see how lazy and eager evaluation affect how long a program takes to run.
Specifically, how does the way values are computed change the work done as input grows?
Analyze the time complexity of the following Kotlin code using lazy and eager lists.
val eagerList = (1..n).map { it * 2 }
val lazySequence = (1..n).asSequence().map { it * 2 }
val eagerSum = eagerList.sum()
val lazySum = lazySequence.sum()
This code creates a list eagerly and a sequence lazily, then sums their values.
Look at what repeats when processing the numbers.
- Primary operation: Multiplying each number by 2 and summing all numbers.
- How many times: Exactly once for each number from 1 to n.
Both eager and lazy methods do the same amount of work for n numbers, but when they do it differs.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 multiplications and 10 additions |
| 100 | About 100 multiplications and 100 additions |
| 1000 | About 1000 multiplications and 1000 additions |
Pattern observation: The total work grows directly with the number of items.
Time Complexity: O(n)
This means the time to complete grows in a straight line as the input size grows.
[X] Wrong: "Lazy evaluation always makes the program faster."
[OK] Correct: Lazy evaluation delays work but does not reduce the total amount of work needed.
Understanding how lazy and eager evaluation affect time helps you explain performance choices clearly.
What if we replaced the sequence with a lazy sequence that filters out half the items before mapping? How would the time complexity change?
Practice
Solution
Step 1: Understand lazy evaluation
Lazy evaluation means the program waits to calculate a value until it is actually needed.Step 2: Understand eager evaluation
Eager evaluation means the program calculates the value right away when the code runs.Final Answer:
Lazy evaluation delays computation until the value is needed, eager evaluation computes immediately. -> Option CQuick Check:
Lazy = delay, Eager = immediate [OK]
- Confusing which evaluation runs first
- Thinking lazy evaluation runs immediately
- Assuming eager evaluation delays work
Solution
Step 1: Recall Kotlin lazy syntax
Kotlin usesval x by lazy { ... }to declare lazy properties.Step 2: Check each option
val x by lazy { 10 } matches the correct syntax. The other options are incorrect Kotlin syntax.Final Answer:
val x by lazy { 10 } -> Option AQuick Check:
Use 'by lazy { }' for lazy properties [OK]
- Using 'lazy val' instead of 'val by lazy'
- Assigning lazy without 'by'
- Placing 'by lazy' after the value
val eager = "Eager".also { println("Eager initialized") }
val lazyVal by lazy { println("Lazy initialized"); "Lazy" }
fun main() {
println("Start main")
println(eager)
println(lazyVal)
println(lazyVal)
}Solution
Step 1: Understand eager initialization
The variableeagerusesalso, so "Eager initialized" prints immediately when declared.Step 2: Understand lazy initialization and main flow
Lazy variablelazyValprints "Lazy initialized" only when first accessed. The main prints "Start main", then printseager(already initialized), then accesseslazyValtwice. The first access triggers initialization print, second does not.Final Answer:
Eager initialized Start main Eager Lazy initialized Lazy Lazy -> Option BQuick Check:
Eager prints first, lazy prints on first access [OK]
- Assuming lazy prints before main
- Thinking lazy prints every access
- Mixing order of prints
val lazyValue by lazy {
println("Calculating...")
42
}
fun main() {
println(lazyValue)
lazyValue = 50
}Solution
Step 1: Check property mutability
The propertylazyValueis declared withval, meaning it cannot be reassigned after initialization.Step 2: Analyze reassignment in main
The code tries to assignlazyValue = 50, which is illegal for avalproperty and causes a compilation error.Final Answer:
Cannot reassign a val property declared with 'by lazy'. -> Option AQuick Check:
val lazy properties are read-only, no reassignment [OK]
- Trying to assign a new value to a val lazy property
- Confusing val with var for lazy properties
- Thinking lazy block must return String
Solution
Step 1: Understand lazy loading benefit
Loading a large config only when needed saves startup time and resources.Step 2: Choose lazy evaluation syntax
Usingval config by lazy { loadConfig() }delays loading until first use, improving performance.Final Answer:
Declare the configuration as val config by lazy { loadConfig() } so it loads only on first access. -> Option DQuick Check:
Lazy loading delays heavy work until needed [OK]
- Loading config immediately even if not needed
- Using var without lazy, causing unnecessary loads
- Loading config repeatedly inside functions
Ready to prove it?
Pass the test and this pattern moves unknown
