Why defer is used in Go - Performance Analysis
We want to understand how using defer affects the time it takes for a Go program to run.
Specifically, we ask: Does defer add extra work as the program runs?
Analyze the time complexity of the following code snippet.
func process(items []int) {
for _, item := range items {
defer cleanup(item)
// do some work with item
}
}
func cleanup(i int) {
// cleanup logic here
}
This code defers cleanup calls for each item in a list, running them after process finishes.
Look for loops or repeated actions that take time.
- Primary operation: Loop over
itemsand calldeferfor each. - How many times: Once per item in the list.
Each item adds one deferred call, so the work to set up defers grows with the number of items.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 defer calls set up |
| 100 | 100 defer calls set up |
| 1000 | 1000 defer calls set up |
Pattern observation: The number of defer setups grows directly with input size.
Time Complexity: O(n)
This means the time to set up all deferred calls grows linearly as the input list gets bigger.
[X] Wrong: "Using defer does not add any extra time cost because it just schedules work for later."
[OK] Correct: Each defer call adds a small overhead immediately to remember the deferred function, so more defers mean more work during the loop.
Understanding how defer affects time helps you write clear and efficient Go code, a skill valued in many coding challenges and real projects.
"What if we moved the defer call outside the loop? How would the time complexity change?"
Practice
defer in Go?Solution
Step 1: Understand the behavior of
Thedeferdeferkeyword postpones the execution of a function until the surrounding function returns.Step 2: Compare options with this behavior
Only To delay a function call until the surrounding function finishes correctly describes this delaying behavior, while others describe unrelated actions.Final Answer:
To delay a function call until the surrounding function finishes -> Option CQuick Check:
Defer delays function calls = A [OK]
- Thinking defer runs function immediately
- Confusing defer with goroutine creation
- Assuming defer declares variables
cleanup() in Go?Solution
Step 1: Recall Go's defer syntax
The correct syntax is the keyworddeferfollowed by the function call without any assignment or punctuation.Step 2: Check each option
Only defer cleanup() matches the correct syntax. Others use invalid symbols or assignment.Final Answer:
defer cleanup() -> Option AQuick Check:
Defer syntax is 'defer function()' = A [OK]
- Adding '=' after defer
- Using ':' or '->' instead of space
- Omitting parentheses on function call
package main
import "fmt"
func main() {
defer fmt.Println("First")
defer fmt.Println("Second")
fmt.Println("Third")
}Solution
Step 1: Identify the order of deferred calls
Deferred calls run after the surrounding function ends, in reverse order of their defer statements. So "Second" runs before "First".Step 2: Trace the print statements
"Third" prints immediately, then deferred prints run: "Second", then "First".Final Answer:
Third\nSecond\nFirst -> Option AQuick Check:
Deferred calls run last in reverse order = C [OK]
- Assuming deferred calls run in order declared
- Thinking deferred calls run immediately
- Mixing up print order
func process() {
defer close(file)
file, err := os.Open("data.txt")
if err != nil {
return
}
// process file
}Solution
Step 1: Analyze the order of statements
The defer statement tries to closefilebeforefileis assigned byos.Open. This causes a compile error becausefileis undefined at defer time.Step 2: Understand defer evaluation timing
Arguments to deferred functions are evaluated immediately, sofilemust be assigned before defer.Final Answer:
Defer is used before file is assigned, causing a compile error -> Option BQuick Check:
Defer arguments evaluated immediately = B [OK]
- Placing defer before variable assignment
- Thinking defer delays argument evaluation
- Assuming defer can't be used with files
defer is best?
func openFiles() {
f1, _ := os.Open("file1.txt")
f2, _ := os.Open("file2.txt")
// What is the best way to defer closing these files?
}Solution
Step 1: Understand resource management with defer
Deferring the close immediately after opening each file ensures each file is closed properly even if the function returns early.Step 2: Compare options
Defer closing each file immediately after opening it defers closing right after opening, which is safe. Defer closing both files together at the end of the function delays both closes until the end, risking leaks if errors occur. Close files manually without defer is error-prone. Use defer only for the last file opened misses closing one file.Final Answer:
Defer closing each file immediately after opening it -> Option DQuick Check:
Defer resource cleanup immediately after acquisition = D [OK]
- Deferring all closes at once at the end
- Not deferring close for every opened file
- Closing files manually without defer
Ready to prove it?
Pass the test and this pattern moves unknown
