axiom-swift-performance

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Swift Performance Optimization

Swift代码性能优化

Purpose

目的

Core Principle: Optimize Swift code by understanding language-level performance characteristics—value semantics, ARC behavior, generic specialization, and memory layout—to write fast, efficient code without premature micro-optimization.
Swift Version: Swift 6.2+ (for InlineArray, Span,
@concurrent
) Xcode: 16+ Platforms: iOS 18+, macOS 15+
Related Skills:
  • axiom-performance-profiling
    — Use Instruments to measure (do this first!)
  • axiom-swiftui-performance
    — SwiftUI-specific optimizations
  • axiom-build-performance
    — Compilation speed
  • axiom-swift-concurrency
    — Correctness-focused concurrency patterns
核心原则:通过理解语言层面的性能特性——值语义、ARC行为、泛型特化和内存布局——来优化Swift代码,编写快速、高效的代码,避免过早的微优化。
Swift版本:Swift 6.2+(支持InlineArray、Span、
@concurrent
Xcode:16+ 支持平台:iOS 18+, macOS 15+
相关技能:
  • axiom-performance-profiling
    — 使用Instruments进行性能测量(请优先使用!)
  • axiom-swiftui-performance
    — SwiftUI专属优化方案
  • axiom-build-performance
    — 编译速度优化
  • axiom-swift-concurrency
    — 以正确性为核心的并发模式

When to Use This Skill

何时使用本技能

✅ Use this skill when

✅ 适用场景

  • App profiling shows Swift code as the bottleneck (Time Profiler hotspots)
  • Excessive memory allocations or retain/release traffic
  • Implementing performance-critical algorithms or data structures
  • Writing framework or library code with performance requirements
  • Optimizing tight loops or frequently called methods
  • Dealing with large data structures or collections
  • Code review identifying performance anti-patterns
  • 应用性能分析显示Swift代码是性能瓶颈(Time Profiler热点代码)
  • 存在过多内存分配或引用计数增减操作
  • 实现性能关键型算法或数据结构
  • 编写有性能要求的框架或库代码
  • 优化循环密集型或频繁调用的方法
  • 处理大型数据结构或集合
  • 代码评审中发现性能反模式

❌ Do NOT use this skill for

❌ 不适用场景

  • First step optimization — Use
    axiom-performance-profiling
    first to measure
  • SwiftUI performance — Use
    axiom-swiftui-performance
    skill instead
  • Build time optimization — Use
    axiom-build-performance
    skill instead
  • Premature optimization — Profile first, optimize later
  • Readability trade-offs — Don't sacrifice clarity for micro-optimizations
  • 首次优化步骤 — 请先使用
    axiom-performance-profiling
    进行性能测量
  • SwiftUI性能优化 — 请使用
    axiom-swiftui-performance
    技能
  • 编译时间优化 — 请使用
    axiom-build-performance
    技能
  • 过早优化 — 先分析性能,再进行优化
  • 可读性权衡 — 不要为了微优化牺牲代码清晰度

Quick Decision Tree

快速决策树

Performance issue identified?
├─ Profiler shows excessive copying?
│  └─ → Part 1: Noncopyable Types
│  └─ → Part 2: Copy-on-Write
├─ Retain/release overhead in Time Profiler?
│  └─ → Part 4: ARC Optimization
├─ Generic code in hot path?
│  └─ → Part 5: Generics & Specialization
├─ Collection operations slow?
│  └─ → Part 7: Collection Performance
├─ Async/await overhead visible?
│  └─ → Part 8: Concurrency Performance
├─ Struct vs class decision?
│  └─ → Part 3: Value vs Reference
└─ Memory layout concerns?
   └─ → Part 9: Memory Layout

是否已识别性能问题?
├─ 性能分析器显示存在过度复制?
│  └─ → 第一部分:不可复制类型
│  └─ → 第二部分:写时复制(COW)
├─ Time Profiler中存在引用计数增减开销?
│  └─ → 第四部分:ARC优化
├─ 热点路径中存在泛型代码?
│  └─ → 第五部分:泛型与特化
├─ 集合操作速度慢?
│  └─ → 第七部分:集合性能优化
├─ 可见Async/await开销?
│  └─ → 第八部分:并发性能优化
├─ 需要在struct和class之间做选择?
│  └─ → 第三部分:值类型与引用类型
└─ 存在内存布局相关问题?
   └─ → 第九部分:内存布局

Part 1: Noncopyable Types (~Copyable)

第一部分:不可复制类型(~Copyable)

Swift 6.0+ introduces noncopyable types for performance-critical scenarios where you want to avoid implicit copies.
Swift 6.0+ 引入了不可复制类型,适用于需要避免隐式复制的性能关键场景。

When to Use

适用场景

  • Large types that should never be copied (file handles, GPU buffers)
  • Types with ownership semantics (must be explicitly consumed)
  • Performance-critical code where copies are expensive
  • 不应被复制的大型类型(如文件句柄、GPU缓冲区)
  • 具有所有权语义的类型(必须显式消耗)
  • 复制成本高昂的性能关键型代码

Basic Pattern

基础模式

swift
// Noncopyable type
struct FileHandle: ~Copyable {
    private let fd: Int32

    init(path: String) throws {
        self.fd = open(path, O_RDONLY)
        guard fd != -1 else { throw FileError.openFailed }
    }

    deinit {
        close(fd)
    }

    // Must explicitly consume
    consuming func close() {
        _ = consume self
    }
}

// Usage
func processFile() throws {
    let handle = try FileHandle(path: "/data.txt")
    // handle is automatically consumed at end of scope
    // Cannot accidentally copy handle
}
swift
// 不可复制类型
struct FileHandle: ~Copyable {
    private let fd: Int32

    init(path: String) throws {
        self.fd = open(path, O_RDONLY)
        guard fd != -1 else { throw FileError.openFailed }
    }

    deinit {
        close(fd)
    }

    // 必须显式消耗
    consuming func close() {
        _ = consume self
    }
}

// 使用示例
func processFile() throws {
    let handle = try FileHandle(path: "/data.txt")
    // handle会在作用域结束时自动被消耗
    // 无法意外复制handle
}

Ownership Annotations

所有权注解

swift
// consuming - takes ownership, caller cannot use after
func process(consuming data: [UInt8]) {
    // data is consumed
}

// borrowing - temporary access without ownership
func validate(borrowing data: [UInt8]) -> Bool {
    // data can still be used by caller
    return data.count > 0
}

// inout - mutable access
func modify(inout data: [UInt8]) {
    data.append(0)
}
swift
// consuming - 获取所有权,调用方之后无法再使用
func process(consuming data: [UInt8]) {
    // data被消耗
}

// borrowing - 临时访问,不获取所有权
func validate(borrowing data: [UInt8]) -> Bool {
    // 调用方仍可使用data
    return data.count > 0
}

// inout - 可变访问
func modify(inout data: [UInt8]) {
    data.append(0)
}

Performance Impact

性能影响

  • Eliminates implicit copies: Compiler error instead of runtime copy
  • Zero-cost abstraction: Same performance as manual memory management
  • Use when: Type is expensive to copy (>64 bytes) and copies are rare

  • 消除隐式复制:编译器会报错,而非在运行时执行复制
  • 零成本抽象:性能与手动内存管理相当
  • 适用时机:类型复制成本高(>64字节)且复制操作很少发生

Part 2: Copy-on-Write (COW)

第二部分:写时复制(COW)

Swift collections use COW for efficient memory sharing. Understanding when copies happen is critical for performance.
Swift集合使用COW实现高效的内存共享。理解复制发生的时机对性能至关重要。

How COW Works

COW工作原理

swift
var array1 = [1, 2, 3]  // Single allocation
var array2 = array1     // Share storage (no copy)
array2.append(4)        // Now copies (array1 modified array2)
swift
var array1 = [1, 2, 3]  // 单次内存分配
var array2 = array1     // 共享存储(无复制)
array2.append(4)        // 此时执行复制(array1和array2分离)

Custom COW Implementation

自定义COW实现

swift
final class Storage<T> {
    var data: [T]
    init(_ data: [T]) { self.data = data }
}

struct COWArray<T> {
    private var storage: Storage<T>

    init(_ data: [T]) {
        self.storage = Storage(data)
    }

    // COW check before mutation
    private mutating func ensureUnique() {
        if !isKnownUniquelyReferenced(&storage) {
            storage = Storage(storage.data)
        }
    }

    mutating func append(_ element: T) {
        ensureUnique()  // Copy if shared
        storage.data.append(element)
    }

    subscript(index: Int) -> T {
        get { storage.data[index] }
        set {
            ensureUnique()  // Copy before mutation
            storage.data[index] = newValue
        }
    }
}
swift
final class Storage<T> {
    var data: [T]
    init(_ data: [T]) { self.data = data }
}

struct COWArray<T> {
    private var storage: Storage<T>

    init(_ data: [T]) {
        self.storage = Storage(data)
    }

    // 变异前执行COW检查
    private mutating func ensureUnique() {
        if !isKnownUniquelyReferenced(&storage) {
            storage = Storage(storage.data)
        }
    }

    mutating func append(_ element: T) {
        ensureUnique()  // 若共享则复制
        storage.data.append(element)
    }

    subscript(index: Int) -> T {
        get { storage.data[index] }
        set {
            ensureUnique()  // 变异前执行复制
            storage.data[index] = newValue
        }
    }
}

Performance Tips

性能优化技巧

swift
// ❌ Accidental copy in loop
for i in 0..<array.count {
    array[i] = transform(array[i])  // Copy on first mutation if shared!
}

// ✅ Reserve capacity first (ensures unique)
array.reserveCapacity(array.count)
for i in 0..<array.count {
    array[i] = transform(array[i])
}

// ❌ Multiple mutations trigger multiple uniqueness checks
array.append(1)
array.append(2)
array.append(3)

// ✅ Single reservation
array.reserveCapacity(array.count + 3)
array.append(contentsOf: [1, 2, 3])

swift
// ❌ 循环中意外触发复制
for i in 0..<array.count {
    array[i] = transform(array[i])  // 若数组被共享,首次变异会触发复制!
}

// ✅ 预先预留容量(确保唯一性)
array.reserveCapacity(array.count)
for i in 0..<array.count {
    array[i] = transform(array[i])
}

// ❌ 多次变异触发多次唯一性检查
array.append(1)
array.append(2)
array.append(3)

// ✅ 单次预留足够容量
array.reserveCapacity(array.count + 3)
array.append(contentsOf: [1, 2, 3])

Part 3: Value vs Reference Semantics

第三部分:值语义与引用语义

Choosing between
struct
and
class
has significant performance implications.
选择
struct
还是
class
对性能有显著影响。

Decision Matrix

决策矩阵

FactorUse StructUse Class
Size≤ 64 bytes> 64 bytes or contains large data
IdentityNo identity neededNeeds identity (===)
InheritanceNot neededInheritance required
MutationInfrequentFrequent in-place updates
SharingNo sharing neededMust be shared across scope
因素使用Struct使用Class
大小≤ 64字节> 64字节或包含大型数据
标识性无需标识需要标识(===)
继承无需继承需要继承
变异变异操作少频繁原地更新
共享无需跨作用域共享必须跨作用域共享

Small Structs (Fast)

小型Struct(性能优异)

swift
// ✅ Fast - fits in registers, no heap allocation
struct Point {
    var x: Double  // 8 bytes
    var y: Double  // 8 bytes
}  // Total: 16 bytes - excellent for struct

struct Color {
    var r, g, b, a: UInt8  // 4 bytes total - perfect for struct
}
swift
// ✅ 性能优异 - 可存入寄存器,无需堆分配
struct Point {
    var x: Double  // 8字节
    var y: Double  // 8字节
}  // 总大小:16字节 - 非常适合用struct

struct Color {
    var r, g, b, a: UInt8  // 共4字节 - 完美适配struct
}

Large Structs (Slow)

大型Struct(性能较差)

swift
// ❌ Slow - excessive copying
struct HugeData {
    var buffer: [UInt8]  // 1MB
    var metadata: String
}

func process(_ data: HugeData) {  // Copies 1MB!
    // ...
}

// ✅ Use reference semantics for large data
final class HugeData {
    var buffer: [UInt8]
    var metadata: String
}

func process(_ data: HugeData) {  // Only copies pointer (8 bytes)
    // ...
}
swift
// ❌ 性能差 - 复制开销大
struct HugeData {
    var buffer: [UInt8]  // 1MB
    var metadata: String
}

func process(_ data: HugeData) {  // 复制1MB数据!
    // ...
}

// ✅ 对大型数据使用引用语义
final class HugeData {
    var buffer: [UInt8]
    var metadata: String
}

func process(_ data: HugeData) {  // 仅复制指针(8字节)
    // ...
}

Indirect Storage for Flexibility

间接存储实现灵活性

swift
// Best of both worlds
struct LargeDataWrapper {
    private final class Storage {
        var largeBuffer: [UInt8]
        init(_ buffer: [UInt8]) { self.largeBuffer = buffer }
    }

    private var storage: Storage

    init(buffer: [UInt8]) {
        self.storage = Storage(buffer)
    }

    // Value semantics externally, reference internally
    var buffer: [UInt8] {
        get { storage.largeBuffer }
        set {
            if !isKnownUniquelyReferenced(&storage) {
                storage = Storage(newValue)
            } else {
                storage.largeBuffer = newValue
            }
        }
    }
}

swift
// 兼顾两者优势
struct LargeDataWrapper {
    private final class Storage {
        var largeBuffer: [UInt8]
        init(_ buffer: [UInt8]) { self.largeBuffer = buffer }
    }

    private var storage: Storage

    init(buffer: [UInt8]) {
        self.storage = Storage(buffer)
    }

    // 外部表现为值语义,内部使用引用语义
    var buffer: [UInt8] {
        get { storage.largeBuffer }
        set {
            if !isKnownUniquelyReferenced(&storage) {
                storage = Storage(newValue)
            } else {
                storage.largeBuffer = newValue
            }
        }
    }
}

Part 4: ARC Optimization

第四部分:ARC优化

Automatic Reference Counting adds overhead. Minimize it where possible.
自动引用计数会带来额外开销,应尽可能减少。

Weak vs Unowned Performance

Weak与Unowned性能对比

swift
class Parent {
    var child: Child?
}

class Child {
    // ❌ Weak adds overhead (optional, thread-safe zeroing)
    weak var parent: Parent?
}

// ✅ Unowned when you know lifetime guarantees
class Child {
    unowned let parent: Parent  // No overhead, crashes if parent deallocated
}
Performance:
unowned
is ~2x faster than
weak
(no atomic operations).
Use when: Child lifetime < Parent lifetime (guaranteed).
swift
class Parent {
    var child: Child?
}

class Child {
    // ❌ Weak引用带来额外开销(可选类型,线程安全的清零操作)
    weak var parent: Parent?
}

// ✅ 当明确生命周期保证时使用Unowned
class Child {
    unowned let parent: Parent  // 无额外开销,若parent已释放会崩溃
}
性能表现
unowned
weak
快约2倍(无需原子操作)。
适用时机:Child的生命周期短于Parent(有明确保证)。

Closure Capture Optimization

闭包捕获优化

swift
class DataProcessor {
    var data: [Int]

    // ❌ Captures self strongly, then uses weak - unnecessary weak overhead
    func process(completion: @escaping () -> Void) {
        DispatchQueue.global().async { [weak self] in
            guard let self else { return }
            self.data.forEach { print($0) }
            completion()
        }
    }

    // ✅ Capture only what you need
    func process(completion: @escaping () -> Void) {
        let data = self.data  // Copy value type
        DispatchQueue.global().async {
            data.forEach { print($0) }  // No self captured
            completion()
        }
    }
}
swift
class DataProcessor {
    var data: [Int]

    // ❌ 强引用捕获self,再使用weak - 不必要的weak开销
    func process(completion: @escaping () -> Void) {
        DispatchQueue.global().async { [weak self] in
            guard let self else { return }
            self.data.forEach { print($0) }
            completion()
        }
    }

    // ✅ 仅捕获需要的内容
    func process(completion: @escaping () -> Void) {
        let data = self.data  // 复制值类型
        DispatchQueue.global().async {
            data.forEach { print($0) }  // 未捕获self
            completion()
        }
    }
}

Reducing Retain/Release Traffic

减少引用计数增减操作

swift
// ❌ Multiple retain/release pairs
for object in objects {
    process(object)  // retain, release
}

// ✅ Single retain for entire loop
func processAll(_ objects: [MyClass]) {
    // Compiler optimizes to single retain/release
    for object in objects {
        process(object)
    }
}
swift
// ❌ 多次引用计数增减
for object in objects {
    process(object)  // retain、release
}

// ✅ 整个循环仅执行一次引用计数操作
func processAll(_ objects: [MyClass]) {
    // 编译器会优化为单次retain/release
    for object in objects {
        process(object)
    }
}

Observable Object Lifetimes

可观察对象的生命周期

From WWDC 2021-10216: Object lifetimes end at last use, not at closing brace.
swift
// ❌ Relying on observed lifetime is fragile
class Traveler {
    weak var account: Account?

    deinit {
        print("Deinitialized")  // May run BEFORE expected with ARC optimizations!
    }
}

func test() {
    let traveler = Traveler()
    let account = Account(traveler: traveler)
    // traveler's last use is above - may deallocate here!
    account.printSummary()  // weak reference may be nil!
}

// ✅ Explicitly extend lifetime when needed
func test() {
    let traveler = Traveler()
    let account = Account(traveler: traveler)

    withExtendedLifetime(traveler) {
        account.printSummary()  // traveler guaranteed to live
    }
}

// Alternative: defer at end of scope
func test() {
    let traveler = Traveler()
    defer { withExtendedLifetime(traveler) {} }

    let account = Account(traveler: traveler)
    account.printSummary()
}
Why This Matters: Observed object lifetimes are an emergent property of compiler optimizations and can change between:
  • Xcode versions
  • Build configurations (Debug vs Release)
  • Unrelated code changes that enable new optimizations
Build Setting: Enable "Optimize Object Lifetimes" (Xcode 13+) during development to expose hidden lifetime bugs early.

来自WWDC 2021-10216:对象的生命周期结束于最后一次使用,而非作用域闭合处。
swift
// ❌ 依赖观察到的生命周期存在风险
class Traveler {
    weak var account: Account?

    deinit {
        print("已释放")  // 在ARC优化下,可能早于预期执行!
    }
}

func test() {
    let traveler = Traveler()
    let account = Account(traveler: traveler)
    // traveler的最后一次使用在上方 - 可能在此处已释放!
    account.printSummary()  // weak引用可能为nil!
}

// ✅ 必要时显式延长生命周期
func test() {
    let traveler = Traveler()
    let account = Account(traveler: traveler)

    withExtendedLifetime(traveler) {
        account.printSummary()  // 保证traveler存活
    }
}

// 替代方案:在作用域末尾使用defer
func test() {
    let traveler = Traveler()
    defer { withExtendedLifetime(traveler) {}}

    let account = Account(traveler: traveler)
    account.printSummary()
}
重要性:观察到的对象生命周期是编译器优化的结果,可能会因以下因素改变:
  • Xcode版本
  • 构建配置(Debug vs Release)
  • 无关代码变更触发新的优化
构建设置:开发期间启用“Optimize Object Lifetimes”(Xcode 13+),提前发现隐藏的生命周期问题。

Part 5: Generics & Specialization

第五部分:泛型与特化

Generic code can be fast or slow depending on specialization.
泛型代码的性能优劣取决于是否进行了特化。

Specialization Basics

特化基础

swift
// Generic function
func process<T>(_ value: T) {
    print(value)
}

// Calling with concrete type
process(42)  // Compiler specializes: process_Int(42)
process("hello")  // Compiler specializes: process_String("hello")
swift
// 泛型函数
func process<T>(_ value: T) {
    print(value)
}

// 使用具体类型调用
process(42)  // 编译器会生成特化版本:process_Int(42)
process("hello")  // 编译器会生成特化版本:process_String("hello")

Existential Overhead

存在类型开销

swift
protocol Drawable {
    func draw()
}

// ❌ Existential container - expensive (heap allocation, indirection)
func drawAll(shapes: [any Drawable]) {
    for shape in shapes {
        shape.draw()  // Dynamic dispatch through witness table
    }
}

// ✅ Generic with constraint - can specialize
func drawAll<T: Drawable>(shapes: [T]) {
    for shape in shapes {
        shape.draw()  // Static dispatch after specialization
    }
}
Performance: Generic version ~10x faster (eliminates witness table overhead).
swift
protocol Drawable {
    func draw()
}

// ❌ 存在类型容器 - 开销大(堆分配、间接访问)
func drawAll(shapes: [any Drawable]) {
    for shape in shapes {
        shape.draw()  // 通过见证表进行动态派发
    }
}

// ✅ 带约束的泛型 - 可进行特化
func drawAll<T: Drawable>(shapes: [T]) {
    for shape in shapes {
        shape.draw()  // 特化后执行静态派发
    }
}
性能表现:泛型版本快约10倍(消除了见证表开销)。

Existential Container Internals

存在类型容器内部实现

From WWDC 2016-416:
any Protocol
uses an existential container with specific performance characteristics.
swift
// Existential Container Memory Layout (64-bit systems)
//
// Small Type (≤24 bytes):
// ┌──────────────────┬──────────────┬────────────────┐
// │ Value (inline)   │ Type         │ Protocol       │
// │ 3 words max      │ Metadata     │ Witness Table  │
// │ (24 bytes)       │ (8 bytes)    │ (8 bytes)      │
// └──────────────────┴──────────────┴────────────────┘
//   ↑ No heap allocation - value stored directly
//
// Large Type (>24 bytes):
// ┌──────────────────┬──────────────┬────────────────┐
// │ Heap Pointer →   │ Type         │ Protocol       │
// │ (8 bytes)        │ Metadata     │ Witness Table  │
// │                  │ (8 bytes)    │ (8 bytes)      │
// └──────────────────┴──────────────┴────────────────┘
//   ↑ Heap allocation required - pointer to actual value
//
// Total container size: 40 bytes (5 words on 64-bit)
// Threshold: 3 words (24 bytes) determines inline vs heap

// Small type example - stored inline (FAST)
struct Point: Drawable {
    var x, y, z: Double  // 24 bytes - fits inline!
}

let drawable: any Drawable = Point(x: 1, y: 2, z: 3)
// ✅ Point stored directly in container (no heap allocation)

// Large type example - heap allocated (SLOWER)
struct Rectangle: Drawable {
    var x, y, width, height: Double  // 32 bytes - exceeds inline buffer
}

let drawable: any Drawable = Rectangle(x: 0, y: 0, width: 10, height: 20)
// ❌ Rectangle allocated on heap, container stores pointer

// Performance comparison:
// - Small existential (≤24 bytes): ~5ns access time
// - Large existential (>24 bytes): ~15ns access time (heap indirection)
// - Generic `some Drawable`: ~2ns access time (no container)
Design Tip: Keep protocol-conforming types ≤24 bytes when used as
any Protocol
for best performance. Use
some Protocol
instead of
any Protocol
when possible to eliminate all container overhead.
来自WWDC 2016-416
any Protocol
使用存在类型容器,具有特定的性能特征。
swift
// 存在类型容器内存布局(64位系统)
//
// 小型类型(≤24字节):
// ┌──────────────────┬──────────────┬────────────────┐
// │ 内联值           │ 类型元数据   │ 协议见证表     │
// │ 最多3个指针大小   │ (8字节)    │ (8字节)      │
// │ (24字节)        │              │                │
// └──────────────────┴──────────────┴────────────────┘
//   ↑ 无需堆分配 - 值直接存储
//
// 大型类型(>24字节):
// ┌──────────────────┬──────────────┬────────────────┐
// │ 堆指针 →         │ 类型元数据   │ 协议见证表     │
// │ (8字节)        │ (8字节)    │ (8字节)      │
// │                  │              │                │
// └──────────────────┴──────────────┴────────────────┘
//   ↑ 需要堆分配 - 容器存储指针
//
// 容器总大小:40字节(64位系统下5个指针大小)
// 阈值:3个指针大小(24字节)决定是内联还是堆存储

// 小型类型示例 - 内联存储(快速)
struct Point: Drawable {
    var x, y, z: Double  // 24字节 - 可内联!
}

let drawable: any Drawable = Point(x: 1, y: 2, z: 3)
// ✅ Point直接存储在容器中(无堆分配)

// 大型类型示例 - 堆分配(较慢)
struct Rectangle: Drawable {
    var x, y, width, height: Double  // 32字节 - 超过内联缓冲区
}

let drawable: any Drawable = Rectangle(x: 0, y: 0, width: 10, height: 20)
// ❌ Rectangle分配在堆上,容器存储指针

// 性能对比:
// - 小型存在类型(≤24字节):约5ns访问时间
// - 大型存在类型(>24字节):约15ns访问时间(堆间接访问)
// - 泛型`some Drawable`:约2ns访问时间(无容器)
设计建议:当使用
any Protocol
时,遵循协议的类型大小应保持≤24字节以获得最佳性能。尽可能使用
some Protocol
替代
any Protocol
,消除所有容器开销。

@_specialize
Attribute

@_specialize
属性

swift
// Force specialization for common types
@_specialize(where T == Int)
@_specialize(where T == String)
func process<T: Comparable>(_ value: T) -> T {
    // Expensive generic operation
    return value
}

// Compiler generates:
// - func process_Int(_ value: Int) -> Int
// - func process_String(_ value: String) -> String
// - Generic fallback for other types
swift
// 强制为常用类型生成特化版本
@_specialize(where T == Int)
@_specialize(where T == String)
func process<T: Comparable>(_ value: T) -> T {
    // 开销大的泛型操作
    return value
}

// 编译器会生成:
// - func process_Int(_ value: Int) -> Int
// - func process_String(_ value: String) -> String
// - 针对其他类型的泛型回退版本

any
vs
some

any
vs
some

swift
// ❌ any - existential, runtime overhead
func makeDrawable() -> any Drawable {
    return Circle()  // Heap allocation
}

// ✅ some - opaque type, compile-time type
func makeDrawable() -> some Drawable {
    return Circle()  // No overhead, type known at compile time
}

swift
// ❌ any - 存在类型,运行时开销
func makeDrawable() -> any Drawable {
    return Circle()  // 堆分配
}

// ✅ some - 不透明类型,编译时确定类型
func makeDrawable() -> some Drawable {
    return Circle()  // 无开销,编译时已知类型
}

Part 6: Inlining

第六部分:内联

Inlining eliminates function call overhead but increases code size.
内联消除函数调用开销,但会增加代码体积。

When to Inline

内联时机

swift
// ✅ Small, frequently called functions
@inlinable
public func fastAdd(_ a: Int, _ b: Int) -> Int {
    return a + b
}

// ❌ Large functions - code bloat
@inlinable  // Don't do this!
public func complexAlgorithm() {
    // 100 lines of code...
}
swift
// ✅ 小型、频繁调用的函数
@inlinable
public func fastAdd(_ a: Int, _ b: Int) -> Int {
    return a + b
}

// ❌ 大型函数 - 会导致代码膨胀
@inlinable  // 请勿这样做!
public func complexAlgorithm() {
    // 100行代码...
}

Cross-Module Optimization

跨模块优化

swift
// Framework code
public struct Point {
    public var x: Double
    public var y: Double

    // ✅ Inlinable for cross-module optimization
    @inlinable
    public func distance(to other: Point) -> Double {
        let dx = x - other.x
        let dy = y - other.y
        return sqrt(dx*dx + dy*dy)
    }
}

// Client code
let p1 = Point(x: 0, y: 0)
let p2 = Point(x: 3, y: 4)
let d = p1.distance(to: p2)  // Inlined across module boundary
swift
// 框架代码
public struct Point {
    public var x: Double
    public var y: Double

    // ✅ 内联以支持跨模块优化
    @inlinable
    public func distance(to other: Point) -> Double {
        let dx = x - other.x
        let dy = y - other.y
        return sqrt(dx*dx + dy*dy)
    }
}

// 客户端代码
let p1 = Point(x: 0, y: 0)
let p2 = Point(x: 3, y: 4)
let d = p1.distance(to: p2)  // 跨模块边界内联执行

@usableFromInline

@usableFromInline

swift
// Internal helper that can be inlined
@usableFromInline
internal func helperFunction() { }

// Public API that uses it
@inlinable
public func publicAPI() {
    helperFunction()  // Can inline internal function
}
Trade-off:
@inlinable
exposes implementation, prevents future optimization.

swift
// 可被内联的内部辅助函数
@usableFromInline
internal func helperFunction() { }

// 使用该辅助函数的公开API
@inlinable
public func publicAPI() {
    helperFunction()  // 可内联内部函数
}
权衡
@inlinable
会暴露实现细节,限制未来的优化空间。

Part 7: Collection Performance

第七部分:集合性能

Choosing the right collection and using it correctly matters.
选择合适的集合并正确使用对性能至关重要。

Array vs ContiguousArray

Array vs ContiguousArray

swift
// ❌ Array<T> - may use NSArray bridging (Swift/ObjC interop)
let array: Array<Int> = [1, 2, 3]

// ✅ ContiguousArray<T> - guaranteed contiguous memory (no bridging)
let array: ContiguousArray<Int> = [1, 2, 3]
Use
ContiguousArray
when
: No ObjC bridging needed (pure Swift), ~15% faster.
swift
// ❌ Array<T> - 可能使用NSArray桥接(Swift/ObjC互操作)
let array: Array<Int> = [1, 2, 3]

// ✅ ContiguousArray<T> - 保证内存连续(无桥接)
let array: ContiguousArray<Int> = [1, 2, 3]
使用
ContiguousArray
的时机
:无需ObjC桥接(纯Swift环境),性能比Array快约15%。

Reserve Capacity

预留容量

swift
// ❌ Multiple reallocations
var array: [Int] = []
for i in 0..<10000 {
    array.append(i)  // Reallocates ~14 times
}

// ✅ Single allocation
var array: [Int] = []
array.reserveCapacity(10000)
for i in 0..<10000 {
    array.append(i)  // No reallocations
}
swift
// ❌ 多次重新分配
var array: [Int] = []
for i in 0..<10000 {
    array.append(i)  // 约重新分配14次
}

// ✅ 单次分配
var array: [Int] = []
array.reserveCapacity(10000)
for i in 0..<10000 {
    array.append(i)  // 无重新分配
}

Dictionary Hashing

字典哈希

swift
struct BadKey: Hashable {
    var data: [Int]

    // ❌ Expensive hash (iterates entire array)
    func hash(into hasher: inout Hasher) {
        for element in data {
            hasher.combine(element)
        }
    }
}

struct GoodKey: Hashable {
    var id: UUID  // Fast hash
    var data: [Int]  // Not hashed

    // ✅ Hash only the unique identifier
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}
swift
struct BadKey: Hashable {
    var data: [Int]

    // ❌ 哈希计算开销大(遍历整个数组)
    func hash(into hasher: inout Hasher) {
        for element in data {
            hasher.combine(element)
        }
    }
}

struct GoodKey: Hashable {
    var id: UUID  // 快速哈希
    var data: [Int]  // 不参与哈希

    // ✅ 仅哈希唯一标识符
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

InlineArray (Swift 6.2)

InlineArray(Swift 6.2)

Fixed-size arrays stored directly on the stack—no heap allocation, no COW overhead.
swift
// Traditional Array - heap allocated, COW overhead
var sprites: [Sprite] = Array(repeating: .default, count: 40)

// InlineArray - stack allocated, no COW
var sprites = InlineArray<40, Sprite>(repeating: .default)
// Alternative syntax (if available)
var sprites: [40 of Sprite] = ...
When to Use InlineArray:
  • Fixed size known at compile time
  • Performance-critical paths (tight loops, hot paths)
  • Want to avoid heap allocation entirely
  • Small to medium sizes (practical limit ~1KB stack usage)
Key Characteristics:
swift
let inline = InlineArray<10, Int>(repeating: 0)

// ✅ Stack allocated - no heap
print(MemoryLayout.size(ofValue: inline))  // 80 bytes (10 × 8)

// ✅ Value semantics - but eagerly copied (not COW!)
var copy = inline  // Copies all 10 elements immediately
copy[0] = 100     // No COW check needed

// ✅ Provides Span access for zero-copy operations
let span = inline.span  // Read-only view
let mutableSpan = inline.mutableSpan  // Mutable view
Performance Comparison:
swift
// Array: Heap allocation + COW overhead
var array = Array(repeating: 0, count: 100)
// - Allocation: ~1μs (heap)
// - Copy: ~50ns (COW reference bump)
// - Mutation: ~50ns (uniqueness check)

// InlineArray: Stack allocation, no COW
var inline = InlineArray<100, Int>(repeating: 0)
// - Allocation: 0ns (stack frame)
// - Copy: ~400ns (eager copy all 100 elements)
// - Mutation: 0ns (no uniqueness check)
24-Byte Threshold Connection:
InlineArray relates to the existential container threshold from Part 5:
swift
// Existential containers store ≤24 bytes inline
struct Small: Protocol {
    var a, b, c: Int64  // 24 bytes - fits inline
}

// InlineArray of 3 Int64s also ≤24 bytes
let inline = InlineArray<3, Int64>(repeating: 0)
// Size: 24 bytes - same threshold, different purpose

// Both avoid heap allocation at this size
let existential: any Protocol = Small(...)  // Inline storage
let array = inline  // Stack storage
Copy Semantics Warning:
swift
// ❌ Unexpected: InlineArray copies eagerly
func processLarge(_ data: InlineArray<1000, UInt8>) {
    // Copies all 1000 bytes on call!
}

// ✅ Use Span to avoid copy
func processLarge(_ data: Span<UInt8>) {
    // Zero-copy view, no matter the size
}

// Best practice: Store InlineArray, pass Span
struct Buffer {
    var storage = InlineArray<1000, UInt8>(repeating: 0)

    func process() {
        helper(storage.span)  // Pass view, not copy
    }
}
When NOT to Use InlineArray:
  • Dynamic sizes (use Array)
  • Large data (>1KB stack usage risky)
  • Frequently passed by value (use Span instead)
  • Need COW semantics (use Array)
固定大小的数组,直接存储在栈上——无堆分配,无COW开销。
swift
// 传统Array - 堆分配,有COW开销
var sprites: [Sprite] = Array(repeating: .default, count: 40)

// InlineArray - 栈分配,无COW
var sprites = InlineArray<40, Sprite>(repeating: .default)
// 替代语法(若可用)
var sprites: [40 of Sprite] = ...
使用InlineArray的时机:
  • 编译时已知固定大小
  • 性能关键路径(循环密集型、热点代码)
  • 希望完全避免堆分配
  • 小型到中型大小(实际限制约1KB栈内存使用)
核心特性:
swift
let inline = InlineArray<10, Int>(repeating: 0)

// ✅ 栈分配 - 无堆内存使用
print(MemoryLayout.size(ofValue: inline))  // 80字节(10 × 8)

// ✅ 值语义 - 但会立即复制(无COW!)
var copy = inline  // 立即复制所有10个元素
copy[0] = 100     // 无需COW检查

// ✅ 提供Span访问以实现零拷贝操作
let span = inline.span  // 只读视图
let mutableSpan = inline.mutableSpan  // 可变视图
性能对比:
swift
// Array: 堆分配 + COW开销
var array = Array(repeating: 0, count: 100)
// - 分配:约1μs(堆)
// - 复制:约50ns(COW引用计数增减)
// - 变异:约50ns(唯一性检查)

// InlineArray: 栈分配,无COW
var inline = InlineArray<100, Int>(repeating: 0)
// - 分配:0ns(栈帧)
// - 复制:约400ns(立即复制所有100个元素)
// - 变异:0ns(无唯一性检查)
与24字节阈值的关联:
InlineArray与第五部分中的存在类型容器阈值相关:
swift
// 存在类型容器可内联存储≤24字节的类型
struct Small: Protocol {
    var a, b, c: Int64  // 24字节 - 可内联
}

// 3个Int64的InlineArray也≤24字节
let inline = InlineArray<3, Int64>(repeating: 0)
// 大小:24字节 - 阈值相同,用途不同

// 两种方式在此大小下都避免了堆分配
let existential: any Protocol = Small(...)  // 内联存储
let array = inline  // 栈存储
复制语义警告:
swift
// ❌ 意外情况:InlineArray会立即复制
func processLarge(_ data: InlineArray<1000, UInt8>) {
    // 调用时会复制全部1000字节!
}

// ✅ 使用Span避免复制
func processLarge(_ data: Span<UInt8>) {
    // 零拷贝视图,无论大小如何
}

// 最佳实践:存储InlineArray,传递Span
struct Buffer {
    var storage = InlineArray<1000, UInt8>(repeating: 0)

    func process() {
        helper(storage.span)  // 传递视图,而非复制
    }
}
不使用InlineArray的时机:
  • 动态大小(使用Array)
  • 大型数据(>1KB栈内存使用有风险)
  • 频繁按值传递(使用Span替代)
  • 需要COW语义(使用Array)

Lazy Sequences

惰性序列

swift
// ❌ Eager evaluation - processes entire array
let result = array
    .map { expensive($0) }
    .filter { $0 > 0 }
    .first  // Only need first element!

// ✅ Lazy evaluation - stops at first match
let result = array
    .lazy
    .map { expensive($0) }
    .filter { $0 > 0 }
    .first  // Only evaluates until first match

swift
// ❌ 立即求值 - 处理整个数组
let result = array
    .map { expensive($0) }
    .filter { $0 > 0 }
    .first  // 仅需第一个元素!

// ✅ 惰性求值 - 找到第一个匹配项后停止
let result = array
    .lazy
    .map { expensive($0) }
    .filter { $0 > 0 }
    .first  // 仅求值到第一个匹配项

Part 8: Concurrency Performance

第八部分:并发性能

Async/await and actors add overhead. Use appropriately.
Async/await和Actor会带来额外开销,应合理使用。

Actor Isolation Overhead

Actor隔离开销

swift
actor Counter {
    private var value = 0

    // ❌ Actor call overhead for simple operation
    func increment() {
        value += 1
    }
}

// Calling from different isolation domain
for _ in 0..<10000 {
    await counter.increment()  // 10,000 actor hops!
}

// ✅ Batch operations to reduce actor overhead
actor Counter {
    private var value = 0

    func incrementBatch(_ count: Int) {
        value += count
    }
}

await counter.incrementBatch(10000)  // Single actor hop
swift
actor Counter {
    private var value = 0

    // ❌ 简单操作的Actor调用开销
    func increment() {
        value += 1
    }
}

// 从不同隔离域调用
for _ in 0..<10000 {
    await counter.increment()  // 10,000次Actor切换!
}

// ✅ 批量操作以减少Actor开销
actor Counter {
    private var value = 0

    func incrementBatch(_ count: Int) {
        value += count
    }
}

await counter.incrementBatch(10000)  // 单次Actor切换

async/await vs Completion Handlers

async/await vs 完成回调

swift
// async/await overhead: ~20-30μs per suspension point

// ❌ Unnecessary async for fast synchronous operation
func compute() async -> Int {
    return 42  // Instant, but pays async overhead
}

// ✅ Keep synchronous operations synchronous
func compute() -> Int {
    return 42  // No overhead
}
swift
// async/await开销:每个挂起点约20-30μs

// ❌ 快速同步操作不必要地使用async
func compute() async -> Int {
    return 42  // 即时完成,但产生async开销
}

// ✅ 同步操作保持同步
func compute() -> Int {
    return 42  // 无开销
}

Task Creation Cost

任务创建成本

swift
// ❌ Creating task per item (~100μs overhead each)
for item in items {
    Task {
        await process(item)
    }
}

// ✅ Single task for batch
Task {
    for item in items {
        await process(item)
    }
}

// ✅ Or use TaskGroup for parallelism
await withTaskGroup(of: Void.self) { group in
    for item in items {
        group.addTask {
            await process(item)
        }
    }
}
swift
// ❌ 为每个元素创建任务(每个任务约100μs开销)
for item in items {
    Task {
        await process(item)
    }
}

// ✅ 单个任务处理批量
Task {
    for item in items {
        await process(item)
    }
}

// ✅ 或使用TaskGroup实现并行
await withTaskGroup(of: Void.self) { group in
    for item in items {
        group.addTask {
            await process(item)
        }
    }
}

@concurrent
Attribute (Swift 6.2)

@concurrent
属性(Swift 6.2)

swift
// Force background execution
@concurrent
func expensiveComputation() -> Int {
    // Always runs on background thread, even if called from MainActor
    return complexCalculation()
}

// Safe to call from main actor without blocking
@MainActor
func updateUI() async {
    let result = await expensiveComputation()  // Guaranteed off main thread
    label.text = "\(result)"
}
swift
// 强制在后台执行
@concurrent
func expensiveComputation() -> Int {
    // 始终在后台线程运行,即使从MainActor调用
    return complexCalculation()
}

// 可安全从主Actor调用而不阻塞
@MainActor
func updateUI() async {
    let result = await expensiveComputation()  // 保证在主线程外执行
    label.text = "\(result)"
}

nonisolated Performance

nonisolated性能

swift
actor DataStore {
    private var data: [Int] = []

    // ❌ Isolated - actor overhead even for read-only
    func getCount() -> Int {
        data.count
    }

    // ✅ nonisolated for immutable state
    nonisolated var storedCount: Int {
        // Must be immutable
        return data.count  // Error: cannot access isolated property
    }
}

swift
actor DataStore {
    private var data: [Int] = []

    // ❌ 即使是只读操作也有Actor开销
    func getCount() -> Int {
        data.count
    }

    // ✅ 不可变状态使用nonisolated
    nonisolated var storedCount: Int {
        // 必须是不可变的
        return data.count  // 错误:无法访问隔离属性
    }
}

Part 9: Memory Layout

第九部分:内存布局

Understanding memory layout helps optimize cache performance and reduce allocations.
理解内存布局有助于优化缓存性能和减少分配。

Struct Padding

Struct填充

swift
// ❌ Poor layout (24 bytes due to padding)
struct BadLayout {
    var a: Bool    // 1 byte + 7 padding
    var b: Int64   // 8 bytes
    var c: Bool    // 1 byte + 7 padding
}
print(MemoryLayout<BadLayout>.size)  // 24 bytes

// ✅ Optimized layout (16 bytes)
struct GoodLayout {
    var b: Int64   // 8 bytes
    var a: Bool    // 1 byte
    var c: Bool    // 1 byte + 6 padding
}
print(MemoryLayout<GoodLayout>.size)  // 16 bytes
swift
// ❌ 布局不佳(因填充导致24字节)
struct BadLayout {
    var a: Bool    // 1字节 + 7字节填充
    var b: Int64   // 8字节
    var c: Bool    // 1字节 + 7字节填充
}
print(MemoryLayout<BadLayout>.size)  // 24字节

// ✅ 优化后布局(16字节)
struct GoodLayout {
    var b: Int64   // 8字节
    var a: Bool    // 1字节
    var c: Bool    // 1字节 + 6字节填充
}
print(MemoryLayout<GoodLayout>.size)  // 16字节

Alignment

对齐

swift
// Query alignment
print(MemoryLayout<Double>.alignment)  // 8
print(MemoryLayout<Int32>.alignment)   // 4

// Structs align to largest member
struct Mixed {
    var int32: Int32   // 4 bytes, 4-byte aligned
    var double: Double // 8 bytes, 8-byte aligned
}
print(MemoryLayout<Mixed>.alignment)  // 8 (largest member)
swift
// 查询对齐要求
print(MemoryLayout<Double>.alignment)  // 8
print(MemoryLayout<Int32>.alignment)   // 4

// Struct的对齐要求与最大成员一致
struct Mixed {
    var int32: Int32   // 4字节,4字节对齐
    var double: Double // 8字节,8字节对齐
}
print(MemoryLayout<Mixed>.alignment)  // 8(最大成员的对齐要求)

Cache-Friendly Data Structures

缓存友好的数据结构

swift
// ❌ Poor cache locality
struct PointerBased {
    var next: UnsafeMutablePointer<Node>?  // Pointer chasing
}

// ✅ Array-based for cache locality
struct ArrayBased {
    var data: ContiguousArray<Int>  // Contiguous memory
}

// Array iteration ~10x faster due to cache prefetching

swift
// ❌ 缓存局部性差
struct PointerBased {
    var next: UnsafeMutablePointer<Node>?  // 指针追踪
}

// ✅ 基于数组实现,缓存局部性好
struct ArrayBased {
    var data: ContiguousArray<Int>  // 连续内存
}

// 数组迭代因缓存预取快约10倍

Part 10: Typed Throws (Swift 6)

第十部分:类型化抛出(Swift 6)

Typed throws can be faster than untyped by avoiding existential overhead.
类型化抛出比非类型化抛出更快,因为避免了存在类型开销。

Untyped vs Typed

非类型化vs类型化

swift
// Untyped - existential container for error
func fetchData() throws -> Data {
    // Can throw any Error
    throw NetworkError.timeout
}

// Typed - concrete error type
func fetchData() throws(NetworkError) -> Data {
    // Can only throw NetworkError
    throw NetworkError.timeout
}
swift
// 非类型化 - 错误使用存在类型容器
func fetchData() throws -> Data {
    // 可抛出任意Error
    throw NetworkError.timeout
}

// 类型化 - 具体错误类型
func fetchData() throws(NetworkError) -> Data {
    // 仅可抛出NetworkError
    throw NetworkError.timeout
}

Performance Impact

性能影响

swift
// Measure with tight loop
func untypedThrows() throws -> Int {
    throw GenericError.failed
}

func typedThrows() throws(GenericError) -> Int {
    throw GenericError.failed
}

// Benchmark: typed ~5-10% faster (no existential overhead)
swift
// 循环测量
func untypedThrows() throws -> Int {
    throw GenericError.failed
}

func typedThrows() throws(GenericError) -> Int {
    throw GenericError.failed
}

// 基准测试:类型化抛出快约5-10%(无存在类型开销)

When to Use

适用时机

  • Typed: Library code with well-defined error types, hot paths
  • Untyped: Application code, error types unknown at compile time

  • 类型化:有明确错误类型的库代码、热点路径
  • 非类型化:应用代码、编译时未知错误类型

Part 11: Span Types

第十一部分:Span类型

Swift 6.2+ introduces Span—a non-escapable, non-owning view into memory that provides safe, efficient access to contiguous data.
Swift 6.2+ 引入了Span——一种非逃逸、非所有权的内存视图,提供安全、高效的连续数据访问。

What is Span?

什么是Span?

Span is a modern replacement for
UnsafeBufferPointer
that provides:
  • Spatial safety: Bounds-checked operations prevent out-of-bounds access
  • Temporal safety: Lifetime inherited from source, preventing use-after-free
  • Zero overhead: No heap allocation, no reference counting
  • Non-escapable: Cannot outlive the data it references
swift
// Traditional unsafe approach
func processUnsafe(_ data: UnsafeMutableBufferPointer<UInt8>) {
    data[100] = 0  // Crashes if out of bounds!
}

// Safe Span approach
func processSafe(_ data: MutableSpan<UInt8>) {
    data[100] = 0  // Traps with clear error if out of bounds
}
Span是
UnsafeBufferPointer
的现代替代方案,提供:
  • 空间安全:边界检查操作防止越界访问
  • 时间安全:生命周期继承自数据源,防止悬垂引用
  • 零开销:无堆分配,无引用计数
  • 非逃逸:无法超过所引用数据的生命周期
swift
// 传统不安全方式
func processUnsafe(_ data: UnsafeMutableBufferPointer<UInt8>) {
    data[100] = 0  // 越界会崩溃!
}

// 安全的Span方式
func processSafe(_ data: MutableSpan<UInt8>) {
    data[100] = 0  // 越界时会触发清晰的错误
}

When to Use Span vs Array vs UnsafeBufferPointer

Span vs Array vs UnsafeBufferPointer的适用场景

Use CaseRecommendation
Own the dataArray (full ownership, COW)
Temporary view for readingSpan (safe, fast)
Temporary view for writingMutableSpan (safe, fast)
C interop, performance-criticalRawSpan (untyped bytes)
Unsafe performanceUnsafeBufferPointer (legacy, avoid)
场景推荐方案
拥有数据所有权Array(完整所有权,COW)
临时只读视图Span(安全、快速)
临时可变视图MutableSpan(安全、快速)
C语言互操作、性能关键场景RawSpan(无类型字节)
不安全的性能优化UnsafeBufferPointer(遗留方案,避免使用)

Basic Span Usage

Span基础用法

swift
let array = [1, 2, 3, 4, 5]

// Get read-only span
let span = array.span
print(span[0])  // 1
print(span.count)  // 5

// Iterate safely
for element in span {
    print(element)
}

// Slicing (creates new span, no copy)
let slice = span[1..<3]  // Span<Int> viewing [2, 3]
swift
let array = [1, 2, 3, 4, 5]

// 获取只读Span
let span = array.span
print(span[0])  // 1
print(span.count)  // 5

// 安全迭代
for element in span {
    print(element)
}

// 切片(创建新Span,无复制)
let slice = span[1..<3]  // 指向[2, 3]的Span<Int>

MutableSpan for Modifications

MutableSpan用于修改

swift
var array = [10, 20, 30, 40, 50]

// Get mutable span
let mutableSpan = array.mutableSpan

// Modify through span
mutableSpan[0] = 100
mutableSpan[1] = 200

print(array)  // [100, 200, 30, 40, 50]

// Safe bounds checking
// mutableSpan[10] = 0  // Fatal error: Index out of range
swift
var array = [10, 20, 30, 40, 50]

// 获取可变Span
let mutableSpan = array.mutableSpan

// 通过Span修改
mutableSpan[0] = 100
mutableSpan[1] = 200

print(array)  // [100, 200, 30, 40, 50]

// 安全边界检查
// mutableSpan[10] = 0  // 致命错误:索引越界

RawSpan for Untyped Bytes

RawSpan用于无类型字节

swift
struct PacketHeader {
    var version: UInt8
    var flags: UInt8
    var length: UInt16
}

func parsePacket(_ data: RawSpan) -> PacketHeader? {
    guard data.count >= MemoryLayout<PacketHeader>.size else {
        return nil
    }

    // Safe byte-level access
    let version = data[0]
    let flags = data[1]
    let lengthLow = data[2]
    let lengthHigh = data[3]

    return PacketHeader(
        version: version,
        flags: flags,
        length: UInt16(lengthHigh) << 8 | UInt16(lengthLow)
    )
}

// Usage
let bytes: [UInt8] = [1, 0x80, 0x00, 0x10]  // Version 1, flags 0x80, length 16
let rawSpan = bytes.rawSpan
if let header = parsePacket(rawSpan) {
    print("Packet version: \(header.version)")
}
swift
struct PacketHeader {
    var version: UInt8
    var flags: UInt8
    var length: UInt16
}

func parsePacket(_ data: RawSpan) -> PacketHeader? {
    guard data.count >= MemoryLayout<PacketHeader>.size else {
        return nil
    }

    // 安全的字节级访问
    let version = data[0]
    let flags = data[1]
    let lengthLow = data[2]
    let lengthHigh = data[3]

    return PacketHeader(
        version: version,
        flags: flags,
        length: UInt16(lengthHigh) << 8 | UInt16(lengthLow)
    )
}

// 使用示例
let bytes: [UInt8] = [1, 0x80, 0x00, 0x10]  // 版本1,标志0x80,长度16
let rawSpan = bytes.rawSpan
if let header = parsePacket(rawSpan) {
    print("Packet version: \(header.version)")
}

Span-Providing Properties

提供Span的属性

Swift 6.2 collections automatically provide span properties:
swift
// Array provides .span and .mutableSpan
let array = [1, 2, 3]
let span: Span<Int> = array.span

// ContiguousArray provides spans
let contiguous = ContiguousArray([1, 2, 3])
let span2 = contiguous.span

// UnsafeBufferPointer provides .span (migration path)
let buffer: UnsafeBufferPointer<Int> = ...
let span3 = buffer.span  // Modern safe wrapper
Swift 6.2集合自动提供Span属性:
swift
// Array提供.span和.mutableSpan
let array = [1, 2, 3]
let span: Span<Int> = array.span

// ContiguousArray提供Span
let contiguous = ContiguousArray([1, 2, 3])
let span2 = contiguous.span

// UnsafeBufferPointer提供.span(迁移路径)
let buffer: UnsafeBufferPointer<Int> = ...
let span3 = buffer.span  // 现代安全包装器

Performance Characteristics

性能特性

swift
// ❌ Array copy - heap allocation
func process(_ array: [Int]) {
    // Array copied if passed across module boundary
}

// ❌ UnsafeBufferPointer - no bounds checking
func process(_ buffer: UnsafeBufferPointer<Int>) {
    buffer[100]  // Crash or memory corruption!
}

// ✅ Span - no copy, bounds-checked, temporal safety
func process(_ span: Span<Int>) {
    span[100]  // Safe trap if out of bounds
}

// Performance: Span is as fast as UnsafeBufferPointer (~2ns access)
// but with safety guarantees (bounds checks are optimized away when safe)
swift
// ❌ Array复制 - 堆分配
func process(_ array: [Int]) {
    // 跨模块传递时会复制Array
}

// ❌ UnsafeBufferPointer - 无边界检查
func process(_ buffer: UnsafeBufferPointer<Int>) {
    buffer[100]  // 崩溃或内存损坏!
}

// ✅ Span - 无复制,边界检查,时间安全
func process(_ span: Span<Int>) {
    span[100]  // 越界时安全触发陷阱
}

// 性能:Span与UnsafeBufferPointer速度相当(约2ns访问时间)
// 但有安全保障(边界检查在安全时会被优化掉)

Non-Escapable Lifetime Safety

非逃逸生命周期安全

swift
// ✅ Safe - span lifetime bound to array
func useSpan() {
    let array = [1, 2, 3, 4, 5]
    let span = array.span
    process(span)  // Safe - array still alive
}

// ❌ Compiler prevents this
func dangerousSpan() -> Span<Int> {
    let array = [1, 2, 3]
    return array.span  // Error: Cannot return non-escapable value
}

// This is what temporal safety prevents
// (Compare to UnsafeBufferPointer which ALLOWS this bug!)
swift
// ✅ 安全 - Span生命周期与Array绑定
func useSpan() {
    let array = [1, 2, 3, 4, 5]
    let span = array.span
    process(span)  // 安全 - Array仍存活
}

// ❌ 编译器会阻止这种情况
func dangerousSpan() -> Span<Int> {
    let array = [1, 2, 3]
    return array.span  // 错误:无法返回非逃逸值
}

// 这正是时间安全所防止的问题
// (对比UnsafeBufferPointer,它允许这种错误!)

Integration with InlineArray

与InlineArray集成

swift
// InlineArray provides span access
let inline = InlineArray<10, UInt8>()
let span: Span<UInt8> = inline.span
let mutableSpan: MutableSpan<UInt8> = inline.mutableSpan

// Efficient zero-copy parsing
func parseHeader(_ span: Span<UInt8>) -> Header {
    // Direct access to inline storage via span
    Header(
        magic: span[0],
        version: span[1],
        flags: span[2]
    )
}

let header = parseHeader(inline.span)  // No heap allocation!
swift
// InlineArray提供Span访问
let inline = InlineArray<10, UInt8>()
let span: Span<UInt8> = inline.span
let mutableSpan: MutableSpan<UInt8> = inline.mutableSpan

// 高效零拷贝解析
func parseHeader(_ span: Span<UInt8>) -> Header {
    // 通过Span直接访问内联存储
    Header(
        magic: span[0],
        version: span[1],
        flags: span[2]
    )
}

let header = parseHeader(inline.span)  // 无堆分配!

Migration from UnsafeBufferPointer

从UnsafeBufferPointer迁移

swift
// Old pattern (unsafe)
func processLegacy(_ buffer: UnsafeBufferPointer<Int>) {
    for i in 0..<buffer.count {
        print(buffer[i])
    }
}

// New pattern (safe)
func processModern(_ span: Span<Int>) {
    for element in span {  // Safe iteration
        print(element)
    }
}

// Migration bridge
let buffer: UnsafeBufferPointer<Int> = ...
let span = buffer.span  // Wrap unsafe pointer in safe span
processModern(span)
swift
// 旧模式(不安全)
func processLegacy(_ buffer: UnsafeBufferPointer<Int>) {
    for i in 0..<buffer.count {
        print(buffer[i])
    }
}

// 新模式(安全)
func processModern(_ span: Span<Int>) {
    for element in span {  // 安全迭代
        print(element)
    }
}

// 迁移桥接
let buffer: UnsafeBufferPointer<Int> = ...
let span = buffer.span  // 现代安全包装器
processModern(span)

Common Patterns

常见模式

swift
// Pattern 1: Binary parsing with RawSpan
func parse<T>(_ span: RawSpan) -> T? {
    guard span.count >= MemoryLayout<T>.size else {
        return nil
    }
    return span.load(as: T.self)  // Safe type reinterpretation
}

// Pattern 2: Chunked processing
func processChunks(_ data: Span<UInt8>, chunkSize: Int) {
    var offset = 0
    while offset < data.count {
        let end = min(offset + chunkSize, data.count)
        let chunk = data[offset..<end]  // Span slice, no copy
        processChunk(chunk)
        offset += chunkSize
    }
}

// Pattern 3: Safe C interop
func sendToC(_ span: Span<UInt8>) {
    span.withUnsafeBufferPointer { buffer in
        // Only escape to unsafe inside controlled scope
        c_function(buffer.baseAddress, buffer.count)
    }
}
swift
// 模式1:使用RawSpan进行二进制解析
func parse<T>(_ span: RawSpan) -> T? {
    guard span.count >= MemoryLayout<T>.size else {
        return nil
    }
    return span.load(as: T.self)  // 安全的类型重解释
}

// 模式2:分块处理
func processChunks(_ data: Span<UInt8>, chunkSize: Int) {
    var offset = 0
    while offset < data.count {
        let end = min(offset + chunkSize, data.count)
        let chunk = data[offset..<end]  // Span切片,无复制
        processChunk(chunk)
        offset += chunkSize
    }
}

// 模式3:安全的C语言互操作
func sendToC(_ span: Span<UInt8>) {
    span.withUnsafeBufferPointer { buffer in
        // 仅在受控作用域内转为不安全指针
        c_function(buffer.baseAddress, buffer.count)
    }
}

When NOT to Use Span

不使用Span的时机

swift
// ❌ Don't use Span for ownership
struct Document {
    var data: Span<UInt8>  // Error: Span can't be stored
}

// ✅ Use Array for owned data
struct Document {
    var data: [UInt8]

    // Provide span access when needed
    var dataSpan: Span<UInt8> {
        data.span
    }
}

// ❌ Don't try to escape Span from scope
func getSpan() -> Span<Int> {  // Error: Non-escapable
    let array = [1, 2, 3]
    return array.span
}

// ✅ Process in scope, return owned data
func processAndReturn() -> [Int] {
    let array = [1, 2, 3]
    process(array.span)  // Process with span
    return array  // Return owned data
}

swift
// ❌ 不要用Span存储数据
struct Document {
    var data: Span<UInt8>  // 错误:Span无法被存储
}

// ✅ 使用Array存储数据
struct Document {
    var data: [UInt8]

    // 需要时提供Span访问
    var dataSpan: Span<UInt8> {
        data.span
    }
}

// ❌ 不要尝试从作用域返回Span
func getSpan() -> Span<Int> {  // 错误:非逃逸值无法返回
    let array = [1, 2, 3]
    return array.span
}

// ✅ 在作用域内处理,返回拥有所有权的数据
func processAndReturn() -> [Int] {
    let array = [1, 2, 3]
    process(array.span)  // 使用Span处理
    return array  // 返回拥有所有权的数据
}

Copy-Paste Patterns

可复制粘贴的模式

Pattern 1: COW Wrapper

模式1:COW包装器

swift
final class Storage<T> {
    var value: T
    init(_ value: T) { self.value = value }
}

struct COWWrapper<T> {
    private var storage: Storage<T>

    init(_ value: T) {
        storage = Storage(value)
    }

    var value: T {
        get { storage.value }
        set {
            if !isKnownUniquelyReferenced(&storage) {
                storage = Storage(newValue)
            } else {
                storage.value = newValue
            }
        }
    }
}
swift
final class Storage<T> {
    var value: T
    init(_ value: T) { self.value = value }
}

struct COWWrapper<T> {
    private var storage: Storage<T>

    init(_ value: T) {
        storage = Storage(value)
    }

    var value: T {
        get { storage.value }
        set {
            if !isKnownUniquelyReferenced(&storage) {
                storage = Storage(newValue)
            } else {
                storage.value = newValue
            }
        }
    }
}

Pattern 2: Performance-Critical Loop

模式2:性能关键型循环

swift
func processLargeArray(_ input: [Int]) -> [Int] {
    var result = ContiguousArray<Int>()
    result.reserveCapacity(input.count)

    for element in input {
        result.append(transform(element))
    }

    return Array(result)
}
swift
func processLargeArray(_ input: [Int]) -> [Int] {
    var result = ContiguousArray<Int>()
    result.reserveCapacity(input.count)

    for element in input {
        result.append(transform(element))
    }

    return Array(result)
}

Pattern 3: Inline Cache Lookup

模式3:内联缓存查找

swift
private var cache: [Key: Value] = [:]

@inlinable
func getCached(_ key: Key) -> Value? {
    return cache[key]  // Inlined across modules
}

swift
private var cache: [Key: Value] = [:]

@inlinable
func getCached(_ key: Key) -> Value? {
    return cache[key]  // 跨模块内联
}

Anti-Patterns

反模式

❌ Anti-Pattern 1: Premature Optimization

❌ 反模式1:过早优化

swift
// Don't optimize without measuring first!

// ❌ Complex optimization with no measurement
struct OverEngineered {
    @usableFromInline var data: ContiguousArray<UInt8>
    // 100 lines of COW logic...
}

// ✅ Start simple, measure, then optimize
struct Simple {
    var data: [UInt8]
}
// Profile → Optimize if needed
swift
// 不要在未测量的情况下进行优化!

// ❌ 无测量的复杂优化
struct OverEngineered {
    @usableFromInline var data: ContiguousArray<UInt8>
    // 100行COW逻辑...
}

// ✅ 从简单开始,测量后再优化
struct Simple {
    var data: [UInt8]
}
// 分析性能 → 必要时优化

❌ Anti-Pattern 2: Weak Everywhere

❌ 反模式2:到处使用Weak

swift
class Manager {
    // ❌ Unnecessary weak reference overhead
    weak var delegate: Delegate?
    weak var dataSource: DataSource?
    weak var observer: Observer?
}

// ✅ Use unowned when lifetime is guaranteed
class Manager {
    unowned let delegate: Delegate  // Delegate outlives Manager
    weak var dataSource: DataSource?  // Optional, may be nil
}
swift
class Manager {
    // ❌ 不必要的Weak引用开销
    weak var delegate: Delegate?
    weak var dataSource: DataSource?
    weak var observer: Observer?
}

// ✅ 生命周期有保证时使用Unowned
class Manager {
    unowned let delegate: Delegate  // Delegate生命周期长于Manager
    weak var dataSource: DataSource?  // 可选,可能为nil
}

❌ Anti-Pattern 3: Actor for Everything

❌ 反模式3:所有场景都用Actor

swift
// ❌ Actor overhead for simple synchronous data
actor SimpleCounter {
    private var count = 0

    func increment() {
        count += 1
    }
}

// ✅ Use lock-free atomics or @unchecked Sendable
import Atomics
struct AtomicCounter: @unchecked Sendable {
    private let count = ManagedAtomic<Int>(0)

    func increment() {
        count.wrappingIncrement(ordering: .relaxed)
    }
}

swift
// ❌ 简单同步数据使用Actor带来开销
actor SimpleCounter {
    private var count = 0

    func increment() {
        count += 1
    }
}

// ✅ 使用无锁原子或@unchecked Sendable
import Atomics
struct AtomicCounter: @unchecked Sendable {
    private let count = ManagedAtomic<Int>(0)

    func increment() {
        count.wrappingIncrement(ordering: .relaxed)
    }
}

Code Review Checklist

代码评审检查清单

Memory Management

内存管理

  • Large structs (>64 bytes) use indirect storage or are classes
  • COW types use
    isKnownUniquelyReferenced
    before mutation
  • Collections use
    reserveCapacity
    when size is known
  • Weak references only where needed (prefer unowned when safe)
  • 大型struct(>64字节)使用间接存储或改为class
  • COW类型在变异前使用
    isKnownUniquelyReferenced
  • 集合在已知大小时使用
    reserveCapacity
  • 仅在必要时使用Weak引用(安全时优先使用Unowned)

Generics

泛型

  • Protocol types use
    some
    instead of
    any
    where possible
  • Hot paths use concrete types or
    @_specialize
  • Generic constraints are as specific as possible
  • 协议类型尽可能使用
    some
    而非
    any
  • 热点路径使用具体类型或
    @_specialize
  • 泛型约束尽可能具体

Collections

集合

  • Pure Swift code uses
    ContiguousArray
    over
    Array
  • Dictionary keys have efficient
    hash(into:)
    implementations
  • Lazy evaluation used for short-circuit operations
  • 纯Swift代码使用
    ContiguousArray
    而非
    Array
  • 字典键实现高效的
    hash(into:)
    方法
  • 短路操作使用惰性求值

Concurrency

并发

  • Synchronous operations don't use
    async
  • Actor calls are batched when possible
  • Task creation is minimized (use TaskGroup)
  • CPU-intensive work uses
    @concurrent
    (Swift 6.2)
  • 同步操作不使用
    async
  • 尽可能批量调用Actor
  • 最小化任务创建(使用TaskGroup)
  • CPU密集型工作使用
    @concurrent
    (Swift 6.2)

Optimization

优化

  • Profiling data exists before optimization
  • Inlining only for small, frequently called functions
  • Memory layout optimized for cache locality (large structs)

  • 优化前有性能分析数据
  • 仅对小型、频繁调用的函数进行内联
  • 大型struct的内存布局优化以提升缓存局部性

Pressure Scenarios

压力场景

Scenario 1: "Just make it faster, we ship tomorrow"

场景1:“赶紧让它变快,我们明天要发布”

The Pressure: Manager sees "slow" in profiler, demands immediate action.
Red Flags:
  • No baseline measurements
  • No Time Profiler data showing hotspots
  • "Make everything faster" without targets
Time Cost Comparison:
  • Premature optimization: 2 days of work, no measurable improvement
  • Profile-guided optimization: 2 hours profiling + 4 hours fixing actual bottleneck = 40% faster
How to Push Back Professionally:
"I want to optimize effectively. Let me spend 30 minutes with Instruments
to find the actual bottleneck. This prevents wasting time on code that's
not the problem. I've seen this save days of work."
压力:经理在性能分析器中看到“缓慢”,要求立即解决。
危险信号:
  • 无基准测量数据
  • 无Time Profiler热点数据
  • “让所有东西变快”但无具体目标
时间成本对比:
  • 过早优化:2天工作,无 measurable 提升
  • 基于分析的优化:2小时分析 + 4小时修复实际瓶颈 = 性能提升40%
专业应对话术:
"我想进行有效的优化。请给我30分钟用Instruments找到实际的性能瓶颈。这能避免在非问题代码上浪费时间。我见过这种方法节省数天的工作量。"

Scenario 2: "Use actors everywhere for thread safety"

场景2:“所有场景都用Actor保证线程安全”

The Pressure: Team adopts Swift 6, decides "everything should be an actor."
Red Flags:
  • Actor for simple value types
  • Actor for synchronous-only operations
  • Async overhead in tight loops
Time Cost Comparison:
  • Actor everywhere: 100μs overhead per operation, janky UI
  • Appropriate isolation: 10μs overhead, smooth 60fps
How to Push Back Professionally:
"Actors are great for isolation, but they add overhead. For this simple
counter, lock-free atomics are 10x faster. Let's use actors where we need
them—shared mutable state—and avoid them for pure value types."
压力:团队采用Swift 6,决定“所有东西都应该是Actor”。
危险信号:
  • 简单值类型使用Actor
  • 仅同步操作使用Actor
  • 循环密集型代码中存在Async开销
时间成本对比:
  • 所有场景用Actor:每次操作100μs开销,UI卡顿
  • 合理隔离:每次操作10μs开销,60fps流畅运行
专业应对话术:
"Actor在隔离方面表现出色,但会带来额外开销。对于这个简单的计数器,无锁原子操作快10倍。我们应该在需要的地方使用Actor——共享可变状态——而纯值类型则避免使用。"

Scenario 3: "Inline everything for speed"

场景3:“所有函数都内联以提升速度”

The Pressure: Someone reads that inlining is faster, marks everything
@inlinable
.
Red Flags:
  • Large functions marked
    @inlinable
  • Internal implementation details exposed
  • Binary size increases 50%
Time Cost Comparison:
  • Inline everything: Code bloat, slower app launch (3s → 5s)
  • Selective inlining: Fast launch, actual hotspots optimized
How to Push Back Professionally:
"Inlining trades code size for speed. The compiler already inlines when
beneficial. Manual @inlinable should be for small, frequently called
functions. Let's profile and inline the 3 actual hotspots, not everything."

压力:某人看到内联能提升速度,给所有函数标记
@inlinable
危险信号:
  • 大型函数标记
    @inlinable
  • 暴露内部实现细节
  • 二进制大小增加50%
时间成本对比:
  • 所有函数内联:代码膨胀,应用启动变慢(3s → 5s)
  • 选择性内联:启动速度快,仅优化实际热点
专业应对话术:
"内联是用代码体积换取速度。编译器在有益时会自动进行内联。手动@inlinable应该用于小型、频繁调用的函数。我们先分析性能,只优化3个实际的热点,而非所有函数。"

Real-World Examples

真实案例

Example 1: Image Processing Pipeline

案例1:图像处理流水线

Problem: Processing 1000 images takes 30 seconds.
Investigation:
swift
// Original code
func processImages(_ images: [UIImage]) -> [ProcessedImage] {
    var results: [ProcessedImage] = []
    for image in images {
        results.append(expensiveProcess(image))  // Reallocations!
    }
    return results
}
Solution:
swift
func processImages(_ images: [UIImage]) -> [ProcessedImage] {
    var results = ContiguousArray<ProcessedImage>()
    results.reserveCapacity(images.count)  // Single allocation

    for image in images {
        results.append(expensiveProcess(image))
    }

    return Array(results)
}
Result: 30s → 8s (73% faster) by eliminating reallocations.
问题:处理1000张图片需要30秒。
分析:
swift
// 原始代码
func processImages(_ images: [UIImage]) -> [ProcessedImage] {
    var results: [ProcessedImage] = []
    for image in images {
        results.append(expensiveProcess(image))  // 多次重新分配!
    }
    return results
}
解决方案:
swift
func processImages(_ images: [UIImage]) -> [ProcessedImage] {
    var results = ContiguousArray<ProcessedImage>()
    results.reserveCapacity(images.count)  // 单次分配

    for image in images {
        results.append(expensiveProcess(image))
    }

    return Array(results)
}
结果:30秒 → 8秒(提升73%),消除了重新分配开销。

Example 2: Actor Batching for Counter

案例2:Actor批量处理计数器

Problem: Actor counter in tight loop causes UI jank.
Investigation:
swift
// Original - 10,000 actor hops
for _ in 0..<10000 {
    await counter.increment()  // ~100μs each = 1 second total!
}
Solution:
swift
// Batch operations
actor Counter {
    private var value = 0

    func incrementBatch(_ count: Int) {
        value += count
    }
}

await counter.incrementBatch(10000)  // Single actor hop
Result: 1000ms → 0.1ms (10,000x faster) by batching.
问题:循环中调用Actor计数器导致UI卡顿。
分析:
swift
// 原始代码 - 10,000次Actor切换
for _ in 0..<10000 {
    await counter.increment()  // 每次约100μs,总计1秒!
}
解决方案:
swift
// 批量操作
actor Counter {
    private var value = 0

    func incrementBatch(_ count: Int) {
        value += count
    }
}

await counter.incrementBatch(10000)  // 单次Actor切换
结果:1000ms → 0.1ms(快10,000倍),通过批量处理实现。

Example 3: Generic Specialization

案例3:泛型特化

Problem: Protocol-based rendering is slow.
Investigation:
swift
// Original - existential overhead
func render(shapes: [any Shape]) {
    for shape in shapes {
        shape.draw()  // Dynamic dispatch
    }
}
Solution:
swift
// Specialized generic
func render<S: Shape>(shapes: [S]) {
    for shape in shapes {
        shape.draw()  // Static dispatch after specialization
    }
}

// Or use @_specialize
@_specialize(where S == Circle)
@_specialize(where S == Rectangle)
func render<S: Shape>(shapes: [S]) { }
Result: 100ms → 10ms (10x faster) by eliminating witness table overhead.
问题:基于协议的渲染速度慢。
分析:
swift
// 原始代码 - 存在类型开销
func render(shapes: [any Shape]) {
    for shape in shapes {
        shape.draw()  // 动态派发
    }
}
解决方案:
swift
// 特化泛型
func render<S: Shape>(shapes: [S]) {
    for shape in shapes {
        shape.draw()  // 特化后静态派发
    }
}

// 或使用@_specialize
@_specialize(where S == Circle)
@_specialize(where S == Rectangle)
func render<S: Shape>(shapes: [S]) { }
结果:100ms → 10ms(快10倍),消除了见证表开销。

Example 4: Apple Password Monitoring Migration

案例4:Apple密码监控服务迁移

Problem: Apple's Password Monitoring service needed to scale while reducing costs.
Original Implementation: Java-based service
  • High memory usage (gigabytes)
  • 50% Kubernetes cluster utilization
  • Moderate throughput
Swift Rewrite Benefits:
swift
// Key performance wins from Swift's features:

// 1. Deterministic memory management (no GC pauses)
//    - No stop-the-world garbage collection
//    - Predictable latency for real-time processing

// 2. Value semantics + COW
//    - Efficient data sharing without defensive copying
//    - Reduced memory churn

// 3. Zero-cost abstractions
//    - Generic specialization eliminates runtime overhead
//    - Protocol conformances optimized away
Results (Apple's published metrics):
  • 40% throughput increase vs Java implementation
  • 100x memory reduction: Gigabytes → Megabytes
  • 50% Kubernetes capacity freed: Same workload, half the resources
Why This Matters: This real-world production service demonstrates that the performance patterns in this skill (COW, value semantics, generic specialization, ARC) deliver measurable business impact at scale.

问题:Apple的密码监控服务需要在降低成本的同时实现扩容。
原始实现:基于Java的服务
  • 内存占用高(数GB)
  • Kubernetes集群利用率50%
  • 吞吐量中等
Swift重写优势:
swift
// Swift特性带来的关键性能提升:

// 1. 确定性内存管理(无GC停顿)
//    - 无全局停止的垃圾回收
//    - 实时处理的延迟可预测

// 2. 值语义 + COW
//    - 高效的数据共享,无需防御性复制
//    - 减少内存波动

// 3. 零成本抽象
//    - 泛型特化消除运行时开销
//    - 协议一致性被优化掉
结果(Apple发布的指标):
  • 吞吐量提升40% 对比Java实现
  • 内存占用减少100倍:从数GB降至数MB
  • Kubernetes容量释放50%:相同工作量,资源减半
重要性:这个真实的生产级服务证明,本技能中的性能模式(COW、值语义、泛型特化、ARC)在大规模场景下能带来可衡量的业务价值。

Resources

资源

WWDC: 2025-312, 2024-10217, 2024-10170, 2021-10216, 2016-416
Docs: /swift/inlinearray, /swift/span
Skills: axiom-performance-profiling, axiom-swift-concurrency, axiom-swiftui-performance

Last Updated: 2025-12-18 Swift Version: 6.2+ (for InlineArray, Span,
@concurrent
) Status: Production-ready
Remember: Profile first, optimize later. Readability > micro-optimizations.
WWDC:2025-312, 2024-10217, 2024-10170, 2021-10216, 2016-416
文档:/swift/inlinearray, /swift/span
相关技能:axiom-performance-profiling, axiom-swift-concurrency, axiom-swiftui-performance

最后更新:2025-12-18 Swift版本:6.2+(支持InlineArray、Span、
@concurrent
状态:生产可用
谨记:先分析性能,再进行优化。可读性优先于微优化。