SwiftUI Performance Optimization: Benchmarking Different Coding Levels
UFuk ?atalca
Senior Mobile Engineering Manager | MBA+PhD | PSM | PMP? | UI&UX | Digital Banking | Fintech | Enterprise Architecture | Digital Media | HR | Aviation | E-Commerce | Telecommunication | Insurance | Event Speaker | WWDC?
In SwiftUI projects, performance is crucial, both in terms of compile time and runtime execution. Writing the same function in different ways can yield significant performance differences. In this article, we will implement a data filtering function at Intermediate, Upper Intermediate, and Advanced levels and compare their benchmark results. ??
?? Goal
We will create a function inside HomeViewModel that filters an array of data based on a given keyword. We will then evaluate its performance at three different coding levels.
?? Intermediate Syntax
Description: Uses a basic forEach loop and if condition to perform filtering.
class HomeViewModel: ObservableObject {
@Published var items: [String] = ["Apple", "Orange", "Banana", "Grape"]
func filterItems(keyword: String) -> [String] {
var result: [String] = []
for item in items {
if item.contains(keyword) {
result.append(item)
}
}
return result
}
}
?? Why it's slower: Uses a manual append operation inside a loop, leading to unnecessary processing.
?? Upper Intermediate Syntax
Description: Uses Swift’s built-in filter function and a closure for optimization.
class HomeViewModel: ObservableObject {
@Published var items: [String] = ["Apple", "Orange", "Banana", "Grape"]
func filterItems(keyword: String) -> [String] {
return items.filter { $0.contains(keyword) }
}
}
?? Improvement: The filter function directly processes the array, making the code cleaner and more readable.
?? Advanced Syntax
Description: Uses lazy collections and localizedCaseInsensitiveContains for maximum performance.
class HomeViewModel: ObservableObject {
@Published var items: [String] = ["Apple", "Orange", "Banana", "Grape"]
func filterItems(keyword: String) -> [String] {
items.lazy.filter { $0.localizedCaseInsensitiveContains(keyword) }.map { $0 }
}
}
?? Why it's the fastest?:
?? Benchmark Results
?? Observations
? Intermediate Syntax: Traditional approach, slowest due to excessive looping. Suitable for small-scale projects.
? Upper Intermediate Syntax: Cleaner and functional approach, but still processes the entire array.
? Advanced Syntax: lazy evaluation significantly boosts performance in large data sets. Ideal for scalable SwiftUI projects.
1. First Version (Manual Filter):
import XCTest
@testable import YourApp
class HomeViewModelTests: XCTestCase {
var viewModel: HomeViewModel!
override func setUp() {
super.setUp()
viewModel = HomeViewModel()
}
override func tearDown() {
viewModel = nil
super.tearDown()
}
func testFilterItems_ManualFilter_ShouldReturnCorrectItems() {
let keyword = "Apple"
let filteredItems = viewModel.filterItems(keyword: keyword)
let expectedItems = ["Apple"]
XCTAssertEqual(filteredItems, expectedItems)
}
}
2. Second Version (Using filter):
import XCTest
@testable import YourApp
class HomeViewModelTests: XCTestCase {
var viewModel: HomeViewModel!
override func setUp() {
super.setUp()
viewModel = HomeViewModel()
}
override func tearDown() {
viewModel = nil
super.tearDown()
}
func testFilterItems_WithFilterMethod_ShouldReturnCorrectItems() {
let keyword = "Orange"
let filteredItems = viewModel.filterItems(keyword: keyword)
let expectedItems = ["Orange"]
XCTAssertEqual(filteredItems, expectedItems)
}
}
3. Third Version (Using lazy and localizedCaseInsensitiveContains):
import XCTest
@testable import YourApp
class HomeViewModelTests: XCTestCase {
var viewModel: HomeViewModel!
override func setUp() {
super.setUp()
viewModel = HomeViewModel()
}
override func tearDown() {
viewModel = nil
super.tearDown()
}
func testFilterItems_WithLazyAndInsensitiveSearch_ShouldReturnCorrectItems() {
let keyword = "grape"
let filteredItems = viewModel.filterItems(keyword: keyword)
let expectedItems = ["Grape"]
XCTAssertEqual(filteredItems, expectedItems)
}
}
Explanation:
? Each test checks the functionality of a different version of the HomeViewModel.
? The tests focus on filtering specific keywords and returning the correct results.
? The XCTest framework is used, and the results are compared with XCTAssertEqual.
?? Conclusion
When developing SwiftUI applications, ensuring the best performance is just as important as making the code work. If you're working with large datasets, using Advanced Syntax with lazy collections will provide the best efficiency and execution speed.
?? What optimization techniques do you use? Share your thoughts in the comments! ????
?? Visual Representation
Here’s a graphical representation of the performance impact:
?? Key Takeaway: Using lazy collections and optimized methods significantly reduces execution time, making your SwiftUI applications faster and more efficient. ??