Swift performance
Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/swift-performance
When to activate: Swift performance optimization, value types, COW, ARC, Instruments profiling, memory layout, compile-time optimizationFrom its SKILL.md
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill swift-performanceAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.9 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Swift Performance Patterns
Value Type Performance — Copy-on-Write
Swift standard library containers (Array, Dictionary, String) use COW automatically. Implement COW for your own types when they wrap heap-allocated storage.
final class Storage<T> {
var elements: [T]
init(_ elements: [T] = []) { self.elements = elements }
func copy() -> Storage<T> { Storage(elements) }
}
struct MyArray<T> {
private var storage = Storage<T>()
mutating func append(_ element: T) {
// Only copy if another owner has a reference
if !isKnownUniquelyReferenced(&storage) {
storage = storage.copy()
}
storage.elements.append(element)
}
var count: Int { storage.elements.count }
}
ARC and Retain Cycle Prevention
// Avoid retain cycles with [weak self]
class DataLoader {
var onCompletion: (() -> Void)?
func load() {
fetchData { [weak self] result in // not [unowned] unless certain lifetime
guard let self else { return }
self.process(result)
self.onCompletion?()
}
}
}
// Value types don't participate in ARC — prefer structs for hot data
struct Particle { // no heap allocation, no reference counting
var position: SIMD3<Float>
var velocity: SIMD3<Float>
var mass: Float
}
SIMD for Numerical Work
import simd
// Process 4 floats in parallel using SIMD
func computeDistances(points: [SIMD2<Float>], from origin: SIMD2<Float>) -> [Float] {
points.map { point in
let delta = point - origin
return sqrt(simd_dot(delta, delta))
}
}
// Matrix math with simd
let transform = float4x4(translation: [1, 2, 3])
let position = SIMD4<Float>(1, 0, 0, 1)
let transformed = transform * position
Optimizing Collections
// Reserve capacity for known sizes
var results = [Item]()
results.reserveCapacity(expectedCount)
// Use ContiguousArray for non-class element types (avoids bridging overhead)
var numbers = ContiguousArray<Int>()
// Use lazy for chained transformations that may short-circuit
let firstMatch = items.lazy.filter { $0.isValid }.map { $0.value }.first
// Prefer in-place mutation over creating new collections
items.sort() // faster than: items = items.sorted()
items.removeAll { !$0.isValid }
Whole-Module Optimization
// Package.swift: enable WMO for release builds
swiftSettings: [
.unsafeFlags(["-whole-module-optimization"], .when(configuration: .release)),
]
Instruments Profiling Workflow
- Time Profiler — identify CPU hotspots
- Allocations — find unexpected heap allocation in tight loops
- Leaks — detect reference cycles
- SwiftUI — use SwiftUI instrument to find redundant view updates
// Mark performance-sensitive paths for Instruments
os_signpost(.begin, log: .default, name: "ProcessBatch")
defer { os_signpost(.end, log: .default, name: "ProcessBatch") }
processBatch(items)
Compile-Time Performance
// Break complex type inference for the compiler
// Bad — compiler may time out on complex expressions
let result = items
.filter { $0.isValid }
.map { $0.transform() }
.reduce(0) { $0 + $1.score }
// Good — explicit intermediate types reduce inference work
let valid: [Item] = items.filter { $0.isValid }
let transformed: [T] = valid.map { $0.transform() }
let total: Int = transformed.reduce(0) { $0 + $1.score }
Memory Layout Optimization
// Check struct memory layout
print(MemoryLayout<Particle>.size) // bytes used
print(MemoryLayout<Particle>.stride) // bytes including padding
print(MemoryLayout<Particle>.alignment) // byte alignment
// Reorder fields to minimize padding (largest to smallest alignment)
// Bad: Bool(1) + padding(7) + Double(8) = 16 bytes
struct Bad { var flag: Bool; var value: Double }
// Good: Double(8) + Bool(1) + padding(7) = 16 bytes (same but intentional)
// Even better: group same-size fields together
struct Good { var value: Double; var score: Float; var flag: Bool; var kind: UInt8 }
Common Anti-Patterns
- Classes where structs suffice — classes add heap allocation + ARC overhead
- Closure captures in hot loops — capture values, not references
- Dynamic dispatch for hot paths — use
finalor value types to enable static dispatch - Large value types — structs >~16 bytes can be slower to copy; consider class or indirect enum
- Profiling debug builds — always profile release builds with
-Ooptimizations
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.