Why closures are fundamental in Swift - Performance Analysis
Closures let us write blocks of code that can be used later or multiple times. Understanding their time cost helps us write faster Swift programs.
We want to know how the time to run code with closures changes as we use them more or in different ways.
Analyze the time complexity of the following code snippet.
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { number in
return number * 2
}
print(doubled)
This code uses a closure inside the map function to double each number in an array.
- Primary operation: The closure runs once for each item in the array.
- How many times: Exactly as many times as there are items in the array.
Each new item means the closure runs one more time, so the total work grows steadily with the number of items.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 closure calls |
| 100 | 100 closure calls |
| 1000 | 1000 closure calls |
Pattern observation: The work grows in a straight line as input grows.
Time Complexity: O(n)
This means the time to run the code grows directly with the number of items processed by the closure.
[X] Wrong: "Closures always slow down code a lot because they add extra steps."
[OK] Correct: Closures themselves just run code like any function. The main time depends on how many times the closure runs, not that it is a closure.
Knowing how closures affect time helps you explain your code choices clearly and shows you understand how Swift runs your programs efficiently.
"What if the closure inside map called another function that loops over the array again? How would the time complexity change?"
Practice
Closures are best described as:Solution
Step 1: Understand the definition of closures
Closures are self-contained blocks of functionality that can be passed around and used in your code.Step 2: Match the description to the options
Blocks of code that can be saved and used later correctly describes closures as blocks of code saved for later use, unlike variables, loops, or constants.Final Answer:
Blocks of code that can be saved and used later -> Option BQuick Check:
Closure = reusable code block [OK]
- Confusing closures with variables
- Thinking closures are loops
- Mixing closures with constants
Solution
Step 1: Recall closure syntax in Swift
A closure with no parameters and returning Int is declared as { () -> Int in ... }.Step 2: Check each option
let closure = { () -> Int in return 5 } matches the correct syntax. let closure = { return 5 } misses return type and parameters. let closure = (Int) -> { 5 } is invalid syntax. let closure = func() -> Int { 5 } uses function syntax, not closure.Final Answer:
let closure = { () -> Int in return 5 } -> Option AQuick Check:
Closure syntax = { () -> ReturnType in code } [OK]
- Omitting 'in' keyword
- Using function syntax instead of closure
- Missing return type when needed
let multiplyByTwo = { (number: Int) -> Int in
return number * 2
}
print(multiplyByTwo(4))Solution
Step 1: Understand the closure behavior
The closure takes an Int and returns that number multiplied by 2.Step 2: Calculate the output for input 4
4 * 2 = 8, so the print statement outputs 8.Final Answer:
8 -> Option DQuick Check:
4 * 2 = 8 [OK]
- Confusing input and output values
- Expecting the closure to print automatically
- Syntax errors in closure call
let greet = { name: String in
print("Hello, \(name)!")
}Solution
Step 1: Check closure parameter syntax
Closure parameters must include types inside parentheses, like (name: String).Step 2: Identify the error in given code
The code misses parentheses around parameters.Final Answer:
Missing parentheses around parameters -> Option AQuick Check:
Parameters need types in parentheses [OK]
- Omitting parentheses around parameters
- Forgetting parameter types
- Assuming closures must return values
Consider this code:
func makeIncrementer(amount: Int) -> () -> Int {
var total = 0
let incrementer: () -> Int = {
total += amount
return total
}
return incrementer
}
let incrementByTen = makeIncrementer(amount: 10)
print(incrementByTen())
print(incrementByTen())What will be the output?
Solution
Step 1: Understand closure capturing
The closure captures the variable 'total' from its surrounding context and modifies it each time it runs.Step 2: Trace the output of two calls
First call adds 10 to total (0 + 10 = 10), second call adds 10 again (10 + 10 = 20).Final Answer:
10 and 20 -> Option CQuick Check:
Closures capture and update variables [OK]
- Assuming closures do not keep state
- Thinking total resets each call
- Expecting errors due to variable scope
Ready to prove it?
Pass the test and this pattern moves unknown
