关于 swift-concurrency-performance
面向 Swift 开发者的并发性能审查技能,用于诊断异步工作导致的响应迟缓、吞吐下降、内存增长及取消或任务生命周期问题。它强调先定位并发边界与所有权,再提出小范围改动并规划验证。
主要功能
- 01检查任务生命周期与结构化并发
- 02分析 MainActor 与 Actor 竞争
- 03审查取消、流与 continuation
- 04识别异步上下文中的阻塞工作
- 05结合 Instruments 等方式验证改动
适用场景
- 01排查异步工作引起的界面卡顿
- 02调查任务未随导航取消或泄漏
- 03诊断 Actor 队列积压与重复请求
- 04审查 AsyncStream 清理和缓冲行为
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ livsy90/ ios-performance-agent-skills --skill swift-concurrency-performance安装后在 Claude Code 中输入/swift-concurrency-performance确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/actor-reentrancy.mdasyncsequence-and-stream-cleanup.mdblocking-legacy-apis.mdbounded-task-groups.mdcancellation-and-task-lifetime.mdconcurrency-runtime.mdcontinuation-safety.mddiagnostics-and-instruments.mdmainactor-responsiveness.mdswift-6-isolation.mdtask-lifetime-and-structure.md详细介绍
Swift 并发性能
用途
当异步工作影响 UI 响应速度、吞吐量、内存、取消、任务生命周期、Actor 竞争或高负载下的正确性时,使用此技能审查、诊断和改进 Swift 并发代码。
此技能不是通用的 Swift 并发教程,而是一套用于审查性能和响应速度的工作流程。
何时使用此技能
在以下任务中使用此技能:
- 与异步工作相关的 UI 卡顿、交互迟缓、挂起或掉帧;
- 过度创建
Task、任务组、分离任务或无结构并发; MainActor瓶颈、Actor 切换、Actor 队列堆积或 Actor 竞争;- 取消操作无法停止工作、导航泄漏或任务生命周期超出其所有者;
AsyncSequence、AsyncStream、长时间运行的流、缓冲或生产者清理;- continuation 桥接、委托/回调封装,或围绕旧版 API 的异步封装;
- 异步上下文中的阻塞调用、信号量、同步 I/O、锁或协作式线程池耗尽;
- Actor 可重入性、重复的进行中工作、缓存雪崩,或
await后 Actor 状态不一致; - Swift 6 隔离行为、显式隔离、
@concurrent、nonisolated或 Sendable 边界; - Instruments 跟踪记录、日志或生产环境信号表明存在与并发相关的延迟、内存增长或吞吐量下降。
何时不使用此技能
以下情况不要使用此技能:
- 不涉及性能、生命周期或响应速度问题的基本
async/await语法问题; - 并发不在关键路径中的通用架构讨论;
- 纯 SwiftUI 渲染问题,除非异步生命周期工作导致了相关症状;
- 启动性能问题,除非异步启动工作、任务生命周期或 Actor 隔离属于启动路径的一部分;
- 运行时级别的分配、ARC、泛型或存在类型开销,除非它们与并发行为相互影响;
- 服务端并发问题,除非任务专门涉及 Swift 并发性能模式。
如果任务主要属于更具体的领域,请优先使用其他技能:
- 应用启动、首帧、首次交互、主程序执行前、dyld 或 SDK 启动工作,请使用
ios-launch-performance; - SwiftUI 失效、身份、布局、滚动或
body开销,请使用swiftui-performance; - 主要任务是选择或解读性能分析工具时,请使用
ios-performance-profiling; - 分配、ARC 活动、派发、存在类型、泛型或写时复制开销,请使用
swift-runtime-performance。
核心工作流程
- 找出用户可见的症状:UI 卡顿、交互迟缓、吞吐量低、内存增长、重复工作、任务泄漏、取消未生效、Actor 竞争或协作式线程受阻。
- 定位异步边界:
Task、任务组、Actor 方法、MainActor、continuation、流、生命周期回调、委托桥接或旧版阻塞 API。 - 确定生命周期所有者:视图、视图模型、服务、Actor、请求、应用会话、流消费者或分离的后台进程。
- 区分必要工作与可选或可延后的工作。
- 检查并发是否用于表达结构、隔离和取消,而不是作为含糊的性能修复手段。
- 检查异步上下文中是否存在阻塞工作。
- 检查影响 UI 状态的工作是否经过精确隔离,以及 CPU 密集型工作是否远离主 Actor。
- 检查取消传播,尤其是跨越任务组、流、continuation、循环和导航生命周期的情况。
- 检查 Actor 隔离方法中每个
await之后是否存在 Actor 可重入性问题。 - 提出能够改善生命周期、取消、隔离或吞吐量的最小安全改动。
- 在将改动称为性能改进之前,提供验证方法。
决策规则
- 将
async视为挂起,而非自动在后台执行。 - 不要假设并发会提升性能。更多任务可能增加调度开销、内存压力、Actor 争用和取消复杂度。
- 如果父级负责管理任务的生命周期,优先使用结构化并发。
- 仅当任务的生命周期有意独立,且取消责任明确时,才使用非结构化任务。
- 仅将
Task.detached用作显式逃离继承上下文、优先级、任务局部值和 Actor 隔离的手段。 - 当输入规模可能增长时,限制并行工作量。
- 保持
MainActor上的工作简短,并聚焦于 UI 状态、界面呈现协调和仅限主线程使用的 API。 - 将 CPU 密集型工作移出主 Actor 隔离范围,但不要随意跨越隔离边界。
- 在热点路径上批量处理 Actor 调用,避免反复切换成为主要延迟来源。
- 在 Actor 内部执行
await后,假设 Actor 状态可能已发生变化。 - 默认使用受检查的 continuation,并确认每条路径都恰好恢复一次。
- 将流终止和生产者清理视为 API 契约的一部分。
- 对长时间运行或高吞吐量的工作,优先使用支持取消的循环和流水线。
- 每项性能结论都要有证据或验证计划作为依据。
注意事项
- 不要仅仅因为代码运行缓慢,就建议添加
async或Task。 - 如果 API 或 UI 状态必须保持主 Actor 隔离,就不要将工作移出
MainActor。 - 不要仅仅因为某个
@MainActor类型也负责管理 UI 状态,就把 CPU 密集型计算留在其中。 - 不要为了消除隔离错误而使用
Task.detached,却不说明其对生命周期、取消、优先级和数据安全的影响。 - 对大型或无界集合,不要在未限制并发的情况下为每个元素创建一个子任务。
- 不要用宽泛的
catch块吞掉取消。 - 不要假设取消父任务会自动停止旧式回调、流、代理或手动保留的生产者。
- 如果底层工作仍会阻塞协作式执行器的线程,就不要把阻塞 API 包装成
async。 - 当缓存未命中时 Actor 方法会挂起,因此不要将 Actor 隔离当作防止重复工作的机制。
- 除非性能分析表明确实检查到的 continuation 开销不可忽略,且恢复契约已得到验证,否则不要使用不安全的 continuation。
- 未经过前后验证,不要宣称优化成功。
参考资料路由
仅在相关时阅读:
references/concurrency-runtime.md— 当任务需要了解任务、挂起、协作式执行器、Actor 执行器、优先级、结构化并发,或阻塞异步代码为何有害时阅读。references/mainactor-responsiveness.md— 当任务涉及MainActor、@MainActor类型、UI 状态、视图模型、主线程卡顿、@concurrent,或将 CPU 密集型工作移出 UI 隔离域时阅读。references/task-lifetime-and-structure.md— 当任务涉及结构化并发、非结构化任务、任务所有权、Task {}、Task.detached、视图/视图模型生命周期,或超出其所有者生命周期的任务时阅读。references/cancellation-and-task-lifetime.md— 当任务涉及导航取消、长时间运行的工作、取消传播、被catch吞掉的取消、任务组、流,或取消测试时阅读。references/bounded-task-groups.md— 当任务涉及withTaskGroup、withThrowingTaskGroup、并行映射、扇出工作、内存峰值,或限制并发数时阅读。references/actor-reentrancy.md— 当任务涉及 Actor 隔离状态、重复网络请求、缓存击穿、await前后的状态检查,或 Actor 队列积压时阅读。references/swift-6-isolation.md— 当任务涉及 Swift 6 隔离行为、默认 Actor 隔离、@concurrent、nonisolated、Sendable 边界,或迁移导致的性能回退时阅读。references/blocking-legacy-apis.md— 当任务涉及信号量、同步文件 I/O、阻塞式网络、锁、回调 API、旧版 SDK,或对阻塞工作进行异步封装时阅读。references/continuation-safety.md— 当任务涉及withCheckedContinuation、withCheckedThrowingContinuation、委托桥接、回调封装、超时路径、取消路径,或恰好恢复一次的保证时阅读。references/asyncsequence-and-stream-cleanup.md— 当任务涉及AsyncSequence、AsyncStream、AsyncThrowingStream、长时间运行的流、缓冲、生产者生命周期、onTermination,或for await循环时阅读。references/diagnostics-and-instruments.md— 当用户提供跟踪记录、日志、测量数据、生产环境信号,或询问如何验证并发相关的性能变化时阅读。
验证预期
根据疑似问题推荐合适的验证方式:
- 当症状涉及 UI 卡顿、Actor 争用、任务生命周期、线程阻塞或任务数量过多时,使用 Instruments;
- 比较异步边界前后的延迟时,使用 signposts;
- 当工作应在导航、对象释放、超时或父任务取消后停止时,进行取消测试;
- 当流、任务组或长期运行的任务可能保留生产者或大型值时,使用内存图或分配分析工具;
- 检查是否存在重复的进行中工作时,使用带任务标识符或请求标识符的日志;
- 仅当工作负载足够稳定、能得出有意义的比较结果时,才使用 XCTest 性能测试;
- 当本地跟踪无法复现尾延迟或罕见的卡住任务时,使用生产环境指标。
除非有明确的验证路径,否则不要声称并发重构能提升性能。
输出要求
审查代码时,请按以下格式回复:
- 发现 — 可能存在的并发性能、生命周期、隔离或响应性问题。
- 影响 — 对 UI 延迟、吞吐量、内存、取消、actor 争用或正确性的影响。
- 证据 — 代码模式、跟踪中的症状、生命周期不匹配、缺失的取消路径、阻塞调用、actor 跳转模式,或 continuation/流契约问题。
- 建议的更改 — 首先提出最小且安全的更改;除非设计本身导致问题,否则避免大范围重写。
- 权衡 — 此更改能带来哪些改进,又可能使哪些方面更复杂。
- 验证 — 如何使用 Instruments、signpost、取消测试、日志、内存工具、UI 行为或生产指标来验证结果。
任务要求制定调查计划时,请按以下顺序回复:
- 要复现的症状;
- 可能涉及的异步边界;
- 可能负责管理生命周期或隔离的所有者;
- 首先要收集的跟踪记录或日志;
- 能确认或否定假设的信号;
- 下一步要检查的最小代码范围。
任务要求进行解释时,请务实地回答:
- 简要说明模型;
- 仅在必要时提供一个具体的 iOS 或 Swift 示例;
- 指出常见的误解;
- 提供一种验证或调试方法。 :::
评论
支持 Markdown