performance-profiling
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerformance Profiling
性能分析
Systematic guide for profiling Apple platform apps using Instruments, Xcode diagnostics, and MetricKit. Covers CPU, memory, launch time, and energy analysis with actionable fix patterns.
本指南系统介绍如何使用Instruments、Xcode诊断工具和MetricKit对Apple平台应用进行性能分析,涵盖CPU、内存、启动时间和能耗分析,并提供可落地的修复方案。
When This Skill Activates
技能适用场景
Use this skill when the user:
- Reports app hangs, stutters, or dropped frames
- Needs to profile CPU usage or find hot code paths
- Has memory leaks, high memory usage, or OOM crashes
- Wants to optimize app launch time
- Needs to reduce battery/energy impact
- Asks about Instruments, Time Profiler, Allocations, or Leaks
- Wants to add or performance measurement to code
os_signpost - Is preparing for App Store review and needs performance validation
当用户遇到以下情况时,可使用本技能:
- 反馈应用卡顿、掉帧或运行不流畅
- 需要分析CPU使用率或找出热点代码路径
- 存在内存泄漏、内存占用过高或OOM崩溃问题
- 希望优化应用启动时间
- 需要降低电池/能耗影响
- 询问Instruments、Time Profiler、Allocations或Leaks相关内容
- 希望在代码中添加或性能测量逻辑
os_signpost - 准备进行App Store审核,需要验证应用性能
Decision Tree
决策树
What performance problem are you investigating?
│
├─ App hangs / stutters / dropped frames / slow UI
│ └─ Read time-profiler.md
│
├─ High memory / leaks / OOM crashes / growing footprint
│ └─ Read memory-profiling.md
│
├─ Slow app launch / time to first frame
│ └─ Read launch-optimization.md
│
├─ Battery drain / thermal throttling / background energy
│ └─ Read energy-diagnostics.md
│
├─ General "app feels slow" (unknown cause)
│ └─ Start with time-profiler.md, then memory-profiling.md
│
└─ Pre-release performance audit
└─ Read ALL reference files, use Review Checklist belowWhat performance problem are you investigating?
│
├─ App hangs / stutters / dropped frames / slow UI
│ └─ Read time-profiler.md
│
├─ High memory / leaks / OOM crashes / growing footprint
│ └─ Read memory-profiling.md
│
├─ Slow app launch / time to first frame
│ └─ Read launch-optimization.md
│
├─ Battery drain / thermal throttling / background energy
│ └─ Read energy-diagnostics.md
│
├─ General "app feels slow" (unknown cause)
│ └─ Start with time-profiler.md, then memory-profiling.md
│
└─ Pre-release performance audit
└─ Read ALL reference files, use Review Checklist belowQuick Reference
快速参考
| Problem | Instrument / Tool | Key Metric | Reference |
|---|---|---|---|
| UI hangs > 250ms | Time Profiler + Hangs | Hang duration, main thread stack | time-profiler.md |
| High CPU usage | Time Profiler | CPU % by function, call tree weight | time-profiler.md |
| Memory leak | Leaks + Memory Graph | Leaked bytes, retain cycle paths | memory-profiling.md |
| Memory growth | Allocations | Live bytes, generation analysis | memory-profiling.md |
| Slow launch | App Launch | Time to first frame (pre-main + post-main) | launch-optimization.md |
| Battery drain | Energy Log | Energy Impact score, CPU/GPU/network | energy-diagnostics.md |
| Thermal issues | Activity Monitor | Thermal state transitions | energy-diagnostics.md |
| Network waste | Network profiler | Redundant fetches, large payloads | energy-diagnostics.md |
| 问题 | 工具/Instrument | 关键指标 | 参考文档 |
|---|---|---|---|
| UI卡顿超过250ms | Time Profiler + Hangs | 卡顿时长、主线程堆栈 | time-profiler.md |
| CPU占用过高 | Time Profiler | 各函数CPU占比、调用树权重 | time-profiler.md |
| 内存泄漏 | Leaks + Memory Graph | 泄漏字节数、循环引用路径 | memory-profiling.md |
| 内存持续增长 | Allocations | 活跃字节数、代际分析 | memory-profiling.md |
| 启动缓慢 | App Launch | 首帧时间(main前 + main后) | launch-optimization.md |
| 电池耗电快 | Energy Log | 能耗影响分数、CPU/GPU/网络占用 | energy-diagnostics.md |
| 发热问题 | Activity Monitor | 热状态转换 | energy-diagnostics.md |
| 网络资源浪费 | Network profiler | 冗余请求、大载荷数据 | energy-diagnostics.md |
Process
流程
1. Identify the Problem Category
1. 确定问题类别
Ask the user or inspect their description to classify the issue:
- Responsiveness: Hangs, stutters, animation drops
- Memory: Leaks, growth, OOM crashes
- Launch: Slow cold/warm start
- Energy: Battery drain, thermal throttling
询问用户或查看描述对问题进行分类:
- 响应性:卡顿、掉帧、动画不流畅
- 内存:泄漏、持续增长、OOM崩溃
- 启动:冷启动/热启动缓慢
- 能耗:电池耗电快、热节流
2. Read the Appropriate Reference File
2. 阅读对应参考文档
Each file contains:
- Which Instruments template to use
- Step-by-step profiling workflow
- How to interpret results
- Common fix patterns with code examples
每个文档包含:
- 应使用的Instruments模板
- 分步性能分析流程
- 结果解读方法
- 带代码示例的常见修复方案
3. Profile on Real Hardware
3. 在真实硬件上进行分析
Always remind users:
- Profile on device, not Simulator (Simulator uses host CPU/memory)
- Use Release build configuration (optimizations change behavior)
- Profile with representative data (empty databases hide real perf)
- Close other apps to reduce noise
务必提醒用户:
- 在真机上分析,不要使用模拟器(模拟器使用主机CPU/内存)
- 使用Release构建配置(优化会改变运行行为)
- 使用代表性数据进行分析(空数据库会隐藏真实性能问题)
- 关闭其他应用以减少干扰
4. Apply Fixes and Verify
4. 应用修复并验证
After identifying bottlenecks:
- Apply targeted fix from the reference file
- Re-profile to confirm improvement
- Add markers for ongoing monitoring
os_signpost
识别瓶颈后:
- 从参考文档中应用针对性修复方案
- 重新分析以确认性能提升
- 添加标记以进行持续监控
os_signpost
Xcode Diagnostic Settings
Xcode诊断设置
Recommend enabling these in Scheme > Run > Diagnostics:
| Setting | What It Catches |
|---|---|
| Main Thread Checker | UI work off main thread |
| Thread Sanitizer | Data races |
| Address Sanitizer | Buffer overflows, use-after-free |
| Malloc Stack Logging | Memory allocation call stacks |
| Zombie Objects | Messages to deallocated objects |
建议在Scheme > Run > Diagnostics中启用以下设置:
| 设置 | 检测内容 |
|---|---|
| Main Thread Checker | 主线程外的UI操作 |
| Thread Sanitizer | 数据竞争 |
| Address Sanitizer | 缓冲区溢出、野指针访问 |
| Malloc Stack Logging | 内存分配调用堆栈 |
| Zombie Objects | 向已释放对象发送消息 |
MetricKit Integration
MetricKit集成
For production monitoring, recommend MetricKit:
swift
import MetricKit
final class PerformanceReporter: NSObject, MXMetricManagerSubscriber {
func startCollecting() {
MXMetricManager.shared.add(self)
}
func didReceive(_ payloads: [MXMetricPayload]) {
for payload in payloads {
// Launch time
if let launch = payload.applicationLaunchMetrics {
log("Resume time: \(launch.histogrammedResumeTime)")
}
// Hang rate
if let responsiveness = payload.applicationResponsivenessMetrics {
log("Hang time: \(responsiveness.histogrammedApplicationHangTime)")
}
// Memory
if let memory = payload.memoryMetrics {
log("Peak memory: \(memory.peakMemoryUsage)")
}
}
}
func didReceive(_ payloads: [MXDiagnosticPayload]) {
for payload in payloads {
if let hangs = payload.hangDiagnostics {
for hang in hangs {
log("Hang: \(hang.callStackTree)")
}
}
}
}
}对于生产环境监控,推荐使用MetricKit:
swift
import MetricKit
final class PerformanceReporter: NSObject, MXMetricManagerSubscriber {
func startCollecting() {
MXMetricManager.shared.add(self)
}
func didReceive(_ payloads: [MXMetricPayload]) {
for payload in payloads {
// 启动时间
if let launch = payload.applicationLaunchMetrics {
log("恢复时间: \(launch.histogrammedResumeTime)")
}
// 卡顿率
if let responsiveness = payload.applicationResponsivenessMetrics {
log("卡顿时间: \(responsiveness.histogrammedApplicationHangTime)")
}
// 内存
if let memory = payload.memoryMetrics {
log("峰值内存: \(memory.peakMemoryUsage)")
}
}
}
func didReceive(_ payloads: [MXDiagnosticPayload]) {
for payload in payloads {
if let hangs = payload.hangDiagnostics {
for hang in hangs {
log("卡顿: \(hang.callStackTree)")
}
}
}
}
}Review Checklist
评审检查清单
Responsiveness
响应性
- No synchronous work on main thread > 100ms
- No file I/O or network calls on main thread
- Core Data / SwiftData fetches use background contexts for large queries
- Images decoded off main thread (use or async decoding)
.preparingThumbnail - only on code that truly needs UI access
@MainActor
- 主线程上无超过100ms的同步操作
- 主线程上无文件I/O或网络请求
- Core Data / SwiftData大型查询使用后台上下文
- 图片解码在主线程外进行(使用或异步解码)
.preparingThumbnail - 仅用于真正需要访问UI的代码
@MainActor
Memory
内存
- No retain cycles (check delegate patterns, closures with )
self - Large resources freed when not visible (images, caches)
- Collections don't grow unbounded (capped caches, pagination)
- used in tight loops creating ObjC objects
autoreleasepool
- 无循环引用(检查代理模式、带的闭包)
self - 不可见时释放大型资源(图片、缓存)
- 集合不会无限增长(设置缓存上限、分页)
- 在创建ObjC对象的密集循环中使用
autoreleasepool
Launch Time
启动时间
- No heavy work in of
init()struct@main App - Deferred non-essential initialization (analytics, prefetch)
- Minimal dynamic frameworks (prefer static linking)
- No synchronous network calls at launch
- 结构体的
@main App中无繁重操作init() - 延迟非必要初始化(分析、预取)
- 尽量减少动态框架(优先静态链接)
- 启动时无同步网络请求
Energy
能耗
- Background tasks use appropriately
BGProcessingTaskRequest - Location accuracy matches actual need (not always )
.best - Timers use to allow coalescing
tolerance - Network requests batched where possible
- 后台任务合理使用
BGProcessingTaskRequest - 定位精度匹配实际需求(不总是使用)
.best - 定时器使用允许合并执行
tolerance - 尽可能批量处理网络请求
References
参考资料
- time-profiler.md — CPU profiling, hang detection, signpost API
- memory-profiling.md — Allocations, Leaks, memory graph debugger
- launch-optimization.md — App launch phases, cold/warm start optimization
- energy-diagnostics.md — Battery, thermal state, network efficiency
- WWDC: Ultimate Application Performance Survival Guide
- WWDC: Analyze Hangs with Instruments
- WWDC: Detect and Diagnose Memory Issues
- time-profiler.md — CPU分析、卡顿检测、signpost API
- memory-profiling.md — 内存分配、泄漏检测、内存图调试器
- launch-optimization.md — 应用启动阶段、冷/热启动优化
- energy-diagnostics.md — 电池、热状态、网络效率
- WWDC: Ultimate Application Performance Survival Guide
- WWDC: Analyze Hangs with Instruments
- WWDC: Detect and Diagnose Memory Issues