ios-ettrace-performance
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseiOS ETTrace Performance
iOS ETTrace 性能分析
Use ETTrace for a bounded, symbolicated sampling experiment. Treat capture
conditions and symbolication as part of the evidence, not as setup trivia.
使用ETTrace进行有边界的、已符号化的采样实验。请将捕获条件和符号化视为证据的一部分,而非无关紧要的设置步骤。
Contents
目录
Boundary
适用边界
This skill owns ETTrace framework/CLI capture, exact-build dSYMs, processed
flamegraph JSON, and like-for-like verification. Use Instruments for broad CPU,
hitch, energy, or concurrency triage. Use SwiftUI performance guidance for view
identity, invalidation, and layout remediation.
ETTrace periodically samples thread stacks. Its durations reconstruct sampled
attribution from those intervals; do not present them as wall-clock production
timings or compare them directly with a differently configured profiler.
本技能负责ETTrace框架/CLI捕获、精确构建版本的dSYM、处理后的火焰图JSON以及同类验证。如需进行广泛的CPU、卡顿、能耗或并发问题排查,请使用Instruments。如需针对视图标识、失效和布局修复的指导,请遵循SwiftUI性能优化规范。
ETTrace会定期采样线程堆栈,其时长是通过这些时间间隔重构的采样归因数据;请勿将其视为实际生产环境中的挂钟时间,也不要直接与配置不同的性能分析工具结果进行对比。
Capture Contract
捕获约定
Write these down before capturing:
- one exact user flow and its start/stop boundary;
- launch capture or already-running runtime capture;
- app commit, build configuration, optimization settings, and architecture;
- ETTrace runner and framework versions, plus single-thread or multi-thread mode;
- simulator/device model and OS build;
- launch method, data state, cache state, and repetition count.
Reject a before/after claim when any of these materially differ. Rebuild and
repeat under one contract instead.
在捕获前请记录以下内容:
- 一个明确的用户流程及其开始/结束边界;
- 是启动时捕获还是运行时捕获;
- 应用提交版本、构建配置、优化设置和架构;
- ETTrace运行器和框架版本,以及单线程或多线程模式;
- 模拟器/设备型号和OS版本;
- 启动方式、数据状态、缓存状态和重复次数。
如果上述任何内容存在实质性差异,请拒绝前后对比的结论。应在同一约定下重新构建并重复实验。
Workflow
工作流程
1. Triage before instrumenting
1. 先排查再 instrumentation
Confirm that ETTrace's sampled flamechart is the right next tool. Prefer
Instruments first when the slow interval is unknown, spans many subsystems, or
needs system-level blocking, I/O, hitch, or concurrency context.
Choose one flow small enough to repeat. Launch, first screen construction,
opening one document, or applying one edit are useful boundaries; "use the app"
is not.
确认ETTrace的采样火焰图是合适的下一步工具。当慢执行区间未知、涉及多个子系统,或需要系统级阻塞、I/O、卡顿或并发上下文时,优先使用Instruments。
选择一个足够小且可重复的流程。启动、首屏构建、打开单个文档或执行一次编辑都是有用的边界;“使用应用”则不是。
2. Record and hold ETTrace versions fixed
2. 记录并固定ETTrace版本
Install the runner from the official tap and link the ETTrace package product
into the app target being measured. Record the runner version and the framework
revision or tag separately, then keep both fixed across compared captures. The
bundled analyzer supports the verified v1.1.1 processed output shape; re-check
upstream and the parser before using a different format.
bash
brew install emergetools/homebrew-tap/ettraceRun the instrumented app once and confirm the log. Absence of
that message means capture evidence is not trustworthy. Keep this wiring out of
shipping configurations unless the project deliberately owns that tradeoff.
Starting ETTrace从官方tap安装运行器,并将ETTrace包产品链接到被测应用目标。分别记录运行器版本和框架修订版或标签,然后在所有对比捕获中保持两者固定。内置分析器支持经过验证的v1.1.1处理输出格式;使用其他格式前,请重新检查上游代码和解析器。
bash
brew install emergetools/homebrew-tap/ettrace运行一次instrumented应用,确认出现日志。如果没有该日志,说明捕获数据不可信。除非项目有意承担相关风险,否则请勿将此配置留在发布版本中。
Starting ETTrace3. Build first, then collect matching dSYMs
3. 先构建,再收集匹配的dSYM
Use the final instrumented build for both capture and dSYM collection. Never
choose a dSYM by filename, modification time, or Derived Data proximity.
bash
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.jsonThe helper compares output for the app executable and
embedded binaries. Missing or ambiguous UUID matches stop the run by default.
Read and preserve rather than assuming every copied symbol
file is relevant. The helper fails when UUID matches cannot be copied to unique
flat destination names that ETTrace 1.1.1 can discover.
dwarfdump --uuiddsym-report.json使用最终的instrumented构建版本进行捕获和dSYM收集。切勿通过文件名、修改时间或Derived Data位置来选择dSYM。
bash
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该工具会对比应用可执行文件和嵌入二进制文件的输出。默认情况下,缺失或模糊的UUID匹配会终止运行。请阅读并保留,不要假设所有复制的符号文件都相关。当无法将UUID匹配的文件复制到ETTrace 1.1.1可识别的唯一扁平目标名称时,该工具会执行失败。
dwarfdump --uuiddsym-report.json4. Capture from a clean artifact directory
4. 从干净的产物目录进行捕获
Run ETTrace from an empty directory because processed files are written to the
current working directory. Use for Simulator and for the
exact dSYM directory. Add only for launch work, and follow the
runner's two-launch prompts exactly.
--simulator--dsyms--launchbash
mkdir -p /tmp/myapp-ettrace
mkdir /tmp/myapp-ettrace/run-01
cd /tmp/myapp-ettrace/run-01
ettrace --simulator --dsyms /tmp/myapp-ettrace/dsymsThe second must fail if that per-run directory already exists. Choose a
new run name instead of mixing processed captures from retries.
mkdirLaunch by tapping the app on the Home Screen when the runner asks. Launching
from Xcode can change the launch path and timing. For device capture, omit
; keep all other experiment fields stable.
--simulatorStop immediately after the bounded flow and preserve every fresh
with the capture contract. ETTrace 1.1.1 creates these
processed files after symbolication. Its internal raw runner is a
different artifact and is not accepted by the analyzer below.
output_<threadId>.jsonoutput.json从空目录运行ETTrace,因为处理后的文件会写入当前工作目录。针对模拟器使用参数,针对精确dSYM目录使用参数。仅在捕获启动流程时添加参数,并严格按照运行器的两次启动提示操作。
--simulator--dsyms--launchbash
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完成有边界的流程后立即停止,并将所有新生成的与捕获约定一起保留。ETTrace 1.1.1会在符号化后创建这些处理后的文件。其内部原始运行器是不同的产物,不被下方的分析器接受。
output_<threadId>.jsonoutput.json5. Validate and summarize processed output
5. 验证并总结处理后的输出
bash
python3 scripts/analyze_ettrace.py \
/tmp/myapp-ettrace/run-01/output_*.json \
--top 25 --pretty > /tmp/myapp-ettrace/run-01/summary.jsonThe helper validates the v1.1.1 processed node shape, rejects duplicate inputs
or mixed // metadata, handles the serializer's
object-or-array field, and emits deterministic JSON. It does not
rewrite the capture files. Keep those originals beside the summary.
osBuilddeviceisSimulatorchildrenStop and repair symbolication when important app frames are , raw
addresses, or attributed to the wrong binary. An unsymbolicated hot address is
an evidence gap, not a code recommendation. ETTrace 1.1.1 address-bearing nodes
are listed under and excluded from ordinary hotspots.
<unknown>unresolved_framesbash
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处理后的节点格式,拒绝重复输入或混合的//元数据,处理序列化器的字段(对象或数组类型),并生成确定性JSON。它不会重写捕获文件,请将原始文件与总结文件放在一起保留。
osBuilddeviceisSimulatorchildren当重要的应用帧显示为、原始地址或被归因到错误的二进制文件时,请停止操作并修复符号化问题。未符号化的热点地址是证据缺口,而非代码优化建议。ETTrace 1.1.1中包含地址的节点会列在下,并被排除在常规热点分析之外。
<unknown>unresolved_frames6. Change one cause and repeat
6. 修改一个原因并重复实验
Make the smallest code or configuration change supported by a hot app-owned
path. Rebuild, recollect UUID-matched dSYMs, and capture the same flow at least
twice. Report variance and the full capture contract with the result.
针对热点的应用自有路径,做出最小的代码或配置修改。重新构建、重新收集UUID匹配的dSYM,并至少重复捕获相同流程两次。报告结果时请说明差异情况和完整的捕获约定。
Interpret the Report
报告解读
- Exclusive seconds approximate sampled time charged directly to a symbol after subtracting direct child durations. Start with high exclusive app-owned work.
- Inclusive seconds show the weight of an entire call subtree. Use them to find expensive entry paths, not to blame every parent frame.
- Aggregated inclusive time can exceed the root duration because recursive or nested appearances count each frame. Exclusive percentages use root duration.
- is reported separately. A large value weakens conclusions about what happened in the missing interval.
<unattributed> - A framework hotspot may still be caused by app call frequency, data shape, or configuration. Walk upward to the first controllable app-owned caller.
- Multi-thread files sum thread time, not wall-clock latency. Do not describe their combined root duration as elapsed time.
- Exclusive seconds(独占时间):表示直接归因于某个符号的采样时间近似值,已减去直接子节点的时长。请从占比较高的应用自有独占工作开始分析。
- Inclusive seconds(包含时间):显示整个调用子树的权重。用于查找昂贵的入口路径,而非指责每个父帧。
- 聚合后的包含时间可能超过根节点时长,因为递归或嵌套出现的每个帧都会被计数。独占百分比以根节点时长为基准。
- (未归因)会单独报告。如果该值较大,会削弱对缺失区间内发生情况的结论可信度。
<unattributed> - 框架热点可能仍由应用调用频率、数据格式或配置导致。请向上追溯至第一个可控制的应用自有调用方。
- 多线程文件是线程时间的总和,而非挂钟延迟。请勿将其合并后的根节点时长描述为经过时间。
Common Mistakes
常见误区
- Profiling an unbounded session and then guessing which samples match the bug.
- Capturing one build while supplying dSYMs from another build or architecture.
- Treating ETTrace's raw runner JSON as a processed flamegraph.
- Comparing launch capture with runtime capture, or single-thread with multi-thread capture.
- Optimizing the top inclusive parent without inspecting exclusive work and child paths.
- Claiming improvement from one noisy run.
- Leaving ETTrace instrumentation in production by accident.
- 对无边界的会话进行性能分析,然后猜测哪些采样与bug匹配。
- 捕获一个构建版本的数据,却提供另一个构建版本或架构的dSYM。
- 将ETTrace的原始运行器JSON视为已处理的火焰图。
- 对比启动捕获和运行时捕获,或单线程与多线程捕获的结果。
- 在未检查独占工作和子路径的情况下,优化顶层包含父节点。
- 通过一次噪声较大的运行就声称性能有所提升。
- 意外将ETTrace instrumentation留在生产版本中。
Review Checklist
审核检查清单
- One reproducible flow and start/stop boundary are recorded.
- Launch/runtime capture mode, single/multi-thread mode, runner version, and framework revision match.
- Build configuration, architecture, target/OS, launch method, and app data/cache state match.
- Every capture starts in a fresh, empty per-run artifact directory.
- App and embedded-binary UUIDs match the supplied dSYMs.
- The dSYM collection JSON report is preserved with source/destination and missing, ambiguous, collision, or incompatibility evidence.
- Processed files are preserved unchanged.
output_<threadId>.json - Important app frames are symbolicated.
- Exclusive, inclusive, unattributed, and multi-thread semantics are clear.
- The recommendation names an app-controlled path and supporting evidence.
- Verification repeats the same contract and reports more than one run.
- Temporary instrumentation is removed or intentionally scoped.
- 已记录一个可重现的流程及其开始/结束边界。
- 启动/运行时捕获模式、单/多线程模式、运行器版本和框架修订版保持一致。
- 构建配置、架构、目标/OS、启动方式和应用数据/缓存状态保持一致。
- 每次捕获都从全新的空运行产物目录开始。
- 应用和嵌入二进制文件的UUID与提供的dSYM匹配。
- 已保留dSYM收集JSON报告,其中包含源/目标路径以及缺失、模糊、冲突或不兼容的证据。
- 已保留未修改的处理后文件。
output_<threadId>.json - 重要的应用帧已完成符号化。
- 已明确独占、包含、未归因和多线程的语义。
- 优化建议指明了应用可控路径并提供了支持证据。
- 验证实验遵循同一约定,且报告了多次运行结果。
- 临时instrumentation已移除或被有意限定范围。