mcpField
I
ios-ettrace-performance

ios-ettrace-performance

github.com/dpearson2699开发1.2k1.2k 次安装13 周前更新
代码仓库

关于 ios-ettrace-performance

面向 iOS 开发者的 ETTrace 性能分析技能,用于执行边界明确、可符号化的采样实验。它要求固定采集条件、匹配 dSYM,并以同一工作流重复验证性能变化。

主要功能

  1. 01定义可重复的采样流程和边界
  2. 02匹配构建产物与 dSYM
  3. 03捕获并验证处理后的火焰图数据
  4. 04区分独占时间与包含时间
  5. 05重复同条件采集以验证改动

适用场景

  1. 01分析单个用户操作中的应用耗时路径
  2. 02定位高独占采样时间的应用代码
  3. 03检查符号化问题导致的证据缺口
  4. 04比较优化前后的同一性能流程

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dpearson2699/swift-ios-skills --skill ios-ettrace-performance

安装后在 Claude Code 中输入/ios-ettrace-performance确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

evals/
evals.json
scripts/
analyze_ettrace.py
collect_dsyms.py

详细介绍

iOS ETTrace 性能

使用 ETTrace 开展有明确边界且经过符号化的采样实验。应将采集条件和符号化视为证据的一部分,而非无关紧要的准备工作。

目录

范围界定

本技能负责 ETTrace 框架和 CLI 采集、精确匹配构建版本的 dSYM、处理后的火焰图 JSON,以及同条件验证。对于广泛的 CPU、卡顿、能耗或并发问题排查,请使用 Instruments。对于视图标识、失效和布局修复,请参考 SwiftUI 性能指南。

ETTrace 会定期对线程堆栈进行采样。它根据这些时间间隔重建采样归因的持续时间;不要将其描述为生产环境中的墙钟耗时,也不要直接与配置不同的分析器进行比较。

采集约定

采集前请记录以下信息:

  • 一项明确的用户操作流程及其开始/停止边界;
  • 启动时采集,或在运行中的运行时采集;
  • 应用提交版本、构建配置、优化设置和架构;
  • ETTrace 运行器和框架版本,以及单线程或多线程模式;
  • 模拟器/设备型号和操作系统构建版本;
  • 启动方式、数据状态、缓存状态和重复次数。

如果上述任何条件存在实质性差异,请不要得出前后对比结论。应改为在同一约定下重新构建并重复采集。

工作流

1. 先排查,再添加检测

确认 ETTrace 的采样火焰图是当前合适的工具。如果耗时区间尚不明确、涉及多个子系统,或需要了解系统级阻塞、I/O、卡顿或并发情况,请优先使用 Instruments。

选择一个足够精简、便于重复的操作流程。启动、首次构建屏幕、打开一份文档或应用一次编辑,都是有用的边界;“使用应用”则不是。

2. 固定 ETTrace 版本

从官方 tap 安装运行器,并将 ETTrace 软件包产品链接到被测应用的目标中。分别记录运行器版本和框架修订版或标签,并在对比采集中固定两者。内置分析器支持经验证的 v1.1.1 处理后输出格式;使用其他格式前,请重新检查上游项目和解析器。

brew install emergetools/homebrew-tap/ettrace

运行插桩后的应用一次,并确认日志中出现 Starting ETTrace。如果没有这条消息,采集证据就不可信。除非项目有意承担这一取舍,否则不要在发布配置中保留这些接线设置。

3. 先构建,再收集匹配的 dSYM

采集和收集 dSYM 时都使用最终的插桩构建版本。切勿根据文件名、修改时间或 Derived Data 路径接近程度来选择 dSYM。

mkdir -p /tmp/myapp-ettrace
python3 scripts/collect_dsyms.py \
  --app /path/to/Build/Products/Release-iphonesimulator/MyApp.app \
  --search-root /path/to/Build/Products \
  --search-root /path/to/Archives \
  --output /tmp/myapp-ettrace/dsyms \
  --pretty > /tmp/myapp-ettrace/dsym-report.json

该辅助工具会比较应用可执行文件和内嵌二进制文件的 dwarfdump --uuid 输出。默认情况下,缺少匹配项或 UUID 匹配不明确时会停止运行。请阅读并保留 dsym-report.json,不要想当然地认为每个复制的符号文件都相关。如果无法将 UUID 匹配项复制到 ETTrace 1.1.1 能够发现的唯一扁平目标名称,辅助工具就会失败。

4. 在干净的产物目录中采集

在空目录中运行 ETTrace,因为处理后的文件会写入当前工作目录。对 Simulator 使用 --simulator,并使用 --dsyms 指定确切的 dSYM 目录。仅在分析启动时添加 --launch,并严格按照运行器的两次启动提示操作。

mkdir -p /tmp/myapp-ettrace
mkdir /tmp/myapp-ettrace/run-01
cd /tmp/myapp-ettrace/run-01
ettrace --simulator --dsyms /tmp/myapp-ettrace/dsyms

第二个 mkdir 必须在该次运行目录已存在时失败。请选择新的运行名称,不要将重试采集的处理后文件混在一起。

运行器提示时,通过轻点主屏幕上的应用来启动。从 Xcode 启动可能会改变启动路径和时序。采集设备数据时,省略 --simulator;其他实验字段保持不变。

在限定流程结束后立即停止,并将每个新生成的 output_<threadId>.json 与采集契约一并保留。ETTrace 1.1.1 会在符号化后生成这些处理后的文件。其内部原始运行器文件 output.json 是另一种产物,不能供下方的分析器使用。

5. 验证并汇总处理后的输出
python3 scripts/analyze_ettrace.py \
  /tmp/myapp-ettrace/run-01/output_*.json \
  --top 25 --pretty > /tmp/myapp-ettrace/run-01/summary.json

该辅助工具会验证 v1.1.1 处理后节点的结构,拒绝重复输入或 osBuild/device/isSimulator 元数据不一致的输入,处理序列化器中 children 字段为对象或数组的情况,并生成确定性 JSON。它不会重写采集文件。请将这些原始文件与摘要放在一起保留。

如果重要的应用帧显示为 <unknown>、原始地址,或归属于错误的二进制文件,请停止并修复符号化问题。未符号化的热点地址是证据缺口,而不是代码优化建议。ETTrace 1.1.1 中包含地址的节点会列在 unresolved_frames 下,并从常规热点中排除。

6. 只更改一个原因,然后重复

根据应用自身热点路径上的证据,进行最小幅度的代码或配置更改。重新构建、重新收集 UUID 匹配的 dSYM,并至少两次采集相同流程。报告结果时,同时提供波动情况和完整的采集契约。

解读报告

  • 独占秒数近似表示从直接子级耗时中扣除后,直接计入某个符号的采样时间。优先检查应用自身工作中独占耗时较高的部分。
  • 包含秒数显示整个调用子树的耗时权重。可用它查找开销较大的入口路径,但不要据此归咎于每个父帧。
  • 聚合后的包含时间可能超过根节点耗时,因为递归或嵌套出现时会重复计入每个帧。独占百分比以根节点耗时为基准。
  • <unattributed> 会单独报告。该值较大时,对缺失时间段内发生了什么所作的结论就不那么可靠。
  • 框架热点仍可能由应用调用频率、数据形态或配置导致。沿调用栈向上查找第一个可控的应用自身调用方。
  • 多线程文件统计的是各线程的时间总和,而不是墙钟延迟。不要将它们汇总后的根节点耗时描述为经过时间。

常见错误

  • 分析没有限定范围的会话,然后猜测哪些采样与问题相关。
  • 采集时使用一个构建版本,却提供另一个构建版本或架构的 dSYM。
  • 将 ETTrace 的原始运行器 JSON 当作处理后的火焰图。
  • 比较启动采集与运行时采集,或比较单线程采集与多线程采集。
  • 未检查独占工作和子级路径,就优化包含耗时最高的父级。
  • 根据一次有噪声的运行结果声称性能有所改善。
  • 意外将 ETTrace 插桩留在生产环境中。

审查清单

  • 已记录一个可复现的流程以及开始/停止边界。
  • 启动/运行时捕获模式、单线程/多线程模式、运行器版本和框架修订版本一致。
  • 构建配置、架构、目标平台/操作系统、启动方式以及应用数据/缓存状态一致。
  • 每次捕获都从全新且为空的独立运行产物目录开始。
  • 应用和嵌入式二进制文件的 UUID 与提供的 dSYM 一致。
  • 已保留 dSYM 收集 JSON 报告,其中包含源/目标位置,以及缺失、歧义、冲突或不兼容的证据。
  • 已原样保留处理后的 output_<threadId>.json 文件。
  • 应用的重要帧已完成符号化。
  • 独占、包含、未归属和多线程语义清晰明确。
  • 建议指出由应用控制的路径及其支持证据。
  • 验证遵循相同约定、重复执行,并报告多次运行的结果。
  • 已移除临时插桩,或已明确限定其作用范围。

参考资料

评论

支持 Markdown