Global actors (@MainActor) in Swift - Time & Space Complexity
When using global actors like @MainActor in Swift, it's important to understand how the program's execution time changes as tasks interact with the main thread.
We want to see how the use of @MainActor affects the speed of running code that involves asynchronous calls.
Analyze the time complexity of this Swift code using @MainActor.
@MainActor
class UIUpdater {
func updateUI() {
// update UI elements
}
}
func performTasks(n: Int) async {
let updater = UIUpdater()
for _ in 1...n {
await updater.updateUI()
}
}
This code calls a UI update method on the main actor repeatedly in an asynchronous loop.
Look at what repeats and how often.
- Primary operation: Calling
updateUI()on the@MainActorinstance. - How many times: Exactly
ntimes, once per loop iteration.
Each call waits for the main actor to run the UI update, so the total time grows with the number of calls.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 UI updates on main thread |
| 100 | 100 UI updates on main thread |
| 1000 | 1000 UI updates on main thread |
Pattern observation: The total work increases directly with n, as each update must run one after another on the main actor.
Time Complexity: O(n)
This means the time to complete all UI updates grows linearly with the number of updates requested.
[X] Wrong: "Since the calls are asynchronous, they all run at the same time, so time does not grow with n."
[OK] Correct: Because @MainActor serializes access to the main thread, each call waits for the previous one to finish, so they run one after another, not in parallel.
Understanding how global actors like @MainActor affect execution helps you write safe and efficient Swift code, a skill valuable in many real-world projects.
What if we changed @MainActor to a custom global actor that allows concurrent execution? How would the time complexity change?