已完成2026-08-31

Research 02 · iOS Performance

Codesign4QC:一套已成形的 iOS 采集底座,但指标口径仍需先校准

对当前代码快照的性能采集链路进行静态审查,结合仓库内已有测试和双真机长会话报告,区分“可直接借鉴的工程底座”与“进入 Perfowl 前必须重做的指标与判定逻辑”。

454dbe68ee23mainE1 当前代码历史 E2历史真机记录本轮未复测真机

Executive conclusion

结论先行

总体判断:值得作为 Perfowl 的核心参考项目,借鉴优先级明显高于 client_perf。
Codesign4QC 已经具备 DVT 持续采集、iOS 17+ tunnel、进程重绑、有界事件队列、数据质量计数、场景/Marker、分位数、规则、离线报告和可选 Probe 增强模式,是一条完整的“采集 → 存储 → 分析 → 报告”链路。但 GPU 单位、多场景规则、指标完整度和字段请求存在明确风险,不应整体搬运。
2
采集层:DVT 基础 + Probe 增强
9
日常 UI 指标
2 × 30m
仓库记录的双真机长会话

最值得借鉴

provider 适配、进程 generation、Schema v2 事件流、优先级背压、完整性计数、会话产物和 Probe 失败不影响基础采集。

最需要警惕

GPU 存在 0–1 与 0–100 混用迹象;规则引擎只取第一个场景;部分声明指标根本未向 sysmontap 请求。

快照、范围与证据边界

  • 固定分析快照:454dbe68ee23cfca4a31d318f6597f69f74c2ec2(2026-08-31)。当前未提交文件仅涉及 .DS_Store、一个 dylib 和 P12,未覆盖本报告审查的性能源文件。
  • 主审查文件:tools/performance_collector.pyAppModel.swiftPerformanceCapturePipeline.swiftPerformanceEventRuntime.swiftPerformanceMetrics.swiftModels.swiftPerformanceScenario.swiftPerformanceProbe*.swift及报告生成链路。
  • E1 本轮直接阅读当前源码、测试、Git 历史与已有报告;未修改 Codesign4QC。
  • E2 仓库内记录了 Python/Swift 回归、离线工具、签名和 DMG 验证;这些是已归档结果,本轮没有为静态调研重新打包。
  • 历史真机记录 stage-7a-test-report.md 记录 iOS 17.0 / iOS 16.3.1 各超过 1800 秒的历史真机会话,均无 drop/gap/writer failure;原始会话目录已不在当前工作区,且没有指标对照结果,因此它既不是本轮实测,也不满足 Perfowl 对 E4“真机采集并对照”的完整定义。

Data path

性能采集架构

Device RouteiOS 17+ tunneld;旧系统 usbmux/lockdown
DVT Sessionsysmontap + Graphics 共用长连接
CollectorPython sidecar 约 1 Hz JSONL
PipelineSwift utility 队列解码、背压、批量落盘
Sessionraw / metric / event / CSV / manifest
Analysis场景、Marker、分位数、规则、HTML

基础无侵入层

performance_collector.py 用 DVT sysmontap 读取目标进程,同一 DVT 连接内读取 Graphics。它按 PID 优先匹配,PID 失效后按 executable 重绑,并用 generation 隔离累计量差分。iOS 17+ provider 建链对瞬时 tunnel 错误有 4 次有界退避。

事件与数据质量层

Swift 保留 v1 样本兼容输出,同时转为 Schema v2 统一事件。默认队列容量 2048、批次 64;P0 控制事件可驱逐低优先级数据,P1 可驱逐 P2,同时记录 drop、writer failure、duplicate、out-of-order、sequence gap 和队列峰值。

可选 Probe 增强层

注入的统一 Framework 可上报 display callback、主线程 stall、生命周期、启动 marker、显式 URLSession 指标和传输自监控。HMAC + CRC + sequence/generation 保护通信;Probe 缺失或连接失败时保持 dormant,DVT 基础采集继续。

Metric audit

指标口径与成熟度

领域当前来源范围成熟度Perfowl 决策
CPUDVT cpuUsage目标进程主路可用;多核可超 100%保留原值,另给 normalized/core-count,先做 Xcode 对照
内存Physical Footprint / Resident / Compressed目标进程可借鉴,主指标选择正确保留 scope、source、unit、quality;比较时限定同口径
FPSCoreAnimationFramesPerSecond前台渲染管线秒级趋势;非逐帧、非 App 独占只作基础层;不将 <45 / <30 秒级样本命名为 Jank
GPUDevice / Renderer / Tiler Utilization前台渲染管线单位未闭环建立单一 canonical 单位,原值和归一化值分字段保存
IO / 调度累计值按实际间隔差分目标进程算法可借鉴保留首样本 null、计数回退 null 和 generation 隔离
功耗Power ScoreDVT 相对评分不是瓦特/电流限制在同设备同场景相对对比;后续独立设计热/能耗采集
场景与规则Host Marker + 场景区间 + P10/P95会话分析架构成形,多场景判定有缺陷借鉴模型,重写规则在每个场景/每次 repetition 的展开逻辑
Probe 显示回调CADisplayLink callbackApp 回调节奏边界标注正确保留为诊断信号,与系统最终呈现帧、FrameTime/Jank 分开
Probe 网络业务显式上报 URLSession metrics被接入事务不是全流量作为 SDK 协作模式,不与无侵入网络量混称

优点:Perfowl 可以直接借鉴的能力

1. DVT provider 隔离

iOS 17+ tunnel 与旧系统 usbmux 只停留在 provider 选择层,上层采集器可保持统一。

2. 属性协商

先查 sysmonProcessAttributes,只请求设备支持且业务需要的字段,比固定列索引更稳。

3. 重启可观测

PID 只是瞬时身份;用 executable 重绑并增加 generation,避免累计计数跨进程污染。

4. 质量是一等数据

丢弃、写盘失败、Gap、重复、乱序和队列深度被写入会话,不用“有曲线”代替可信度。

5. 热路径有界

文件句柄长期打开、utility 队列批量写入、UI 仅留最近 120 个样本,图表用极值保留降采样。

6. 会话产物可审计

原始 collector、规范化 metric、统一 event、manifest、capability、analysis 和离线 HTML 形成明确证据链。

7. 基础/增强分层

Probe 只补充主线程、显示回调、启动和业务网络;失败时不拖垮 DVT,且报告不伪造缺失数据。

8. 离线产品化

性能 collector、pymobiledevice3 和报告资源按 arm64/x86_64 打包,HTML 渲染不依赖公网。

Risk register

缺点与需要重做的地方

优先级问题代码证据影响Perfowl 处理
P0GPU 单位混用模型文案和默认规则按 0–100%;activeGPULoadFloor=0.05 注释按 0–1;fixture 使用 0.24,collector 测试使用 17。活跃 FPS 过滤、GPU P95 规则和设备间对比可能失真。先真机固定原始单位,入库时统一归一化;拒绝在 UI 层猜测。
P0多场景规则只检查第一个候选PerformanceScenarioAnalyzer.evaluate 对每条 rule 使用 candidates.first后续场景即使超阈值,也可能被第一场景的 Pass 掩盖。规则明确绑定 scenario selector,逐场景逐轮次评估后再汇总。
P1声明指标未向 sysmontap 请求metric_payload 读取 memAnonmemRPrvtmemVirtualSizemachPortCountnfilesavgPowerScore,但 PROCESS_ATTRIBUTES 不包含它们。字段永远缺失,却仍出现在 model / CSV / 指标字典中。用一份 declarative metric registry 同时驱动请求、解码、完整度和展示。
P1“核心完整度”不包 CPU完整度只计 Physical Footprint、Resident、Compressed、Thread Count。CPU 全程缺失仍可报告 core completeness 100%。按用户选中指标计算 completeness,每指标独立显示 coverage / stale / error。
P1指标选择接口实际无效startPerformanceCapture(selectedMetricIDs:) 接收参数,但立即改为 PerformanceMetricID.available;UI 也固定传入全部。manifest 的 selected 语义与真实采集范围无法作为可信契约。分开 collect-set / display-set / report-set,不用一个字段同时表达三件事。
P1DVT 与 Probe 时钟语义未完全统一DVT sourceMonotonicNs 来自 Mac 侧 collector;Probe payload 包含设备 monotonic;clock_sync 计数被分析,但未见统一映射后的全局时间轴。跨源关联异常时可把 USB/队列延迟误当业务间隔。会话建立 host/device clock model,保留原始时钟与映射误差。
P1默认 Pass 阈值未与刷新率/场景绑定默认规则为 CPU P95 ≤80、Active FPS P10 ≥45、GPU P95 ≤80。120 Hz 、静止界面、重载动画和工具类 App 使用同一判定,Pass 不具备普遍意义。规则必须携带 target FPS、display Hz、场景类型、设备级别和口径版本。
P2长会话报告仍会累积全部数组文件按 64 KB 流式读,但随后把全部 sample 和 event 加入 Swift Array,Probe 高频会话也走同一报告路径。多小时或高频增强模式下,报告生成内存随事件数增长。采用流式聚合 + 窗口索引 + 按需时序,报告不默认加载全部 Probe 事件。
P2Probe 与签名注入域紧耦合增强 Framework 配置、注入、描述文件和 sidecar 管理位于签名 AppModel 主流程。不利于 Perfowl 作为独立性能产品保持模式边界和发布合规。Perfowl Core 只定义 Probe contract;注入/签名作为可选 adapter,基础模式零依赖。

已有验证证明了什么

已有历史证据能支持“链路可长时运行”。
仓库的 7A 报告记录:iOS 17.0 / dvtTunnel 会话 1804.337 秒、1386 个 DVT 样本;iOS 16.3.1 / dvtUSB 会话 1805.471 秒、1496 个样本。两者 accepted = persisted,drop/gap/writer failure 均为 0。
这些数据不能支持“指标已对齐 PerfDog”。
历史长测证明传输、重绑和落盘稳定;它没有与 Xcode Instruments / PerfDog 做 CPU、内存、FPS、GPU 的同场误差比较,也没有完成基线文档预定的静止/动画/压力三场景各 3 轮开销评估。
Probe 证据也要分层。
阶段 10 记录两台设备 20 秒收到 1334 / 1379 个事件,证明 USBMux + HMAC + CRC 传输可用;但报告同时明确 display callback 不是最终呈现帧,不应被命名为真实 Jank。

Perfowl adoption

对 Perfowl 的借鉴清单

决策模块/思想落地方式
直接借鉴iOS provider 路由、tunnel 有界恢复、同 UDID 开发者操作协调抽成 DeviceRuntime / TunnelManager / DVTSession 协议,不放入巨型 ViewModel
直接借鉴PID + executable 重绑、generation 隔离、累计量差分作为 iOS 进程会话的基本契约和回归测试
直接借鉴Schema v2 事件头、P0/P1/P2 背压、质量计数重新命名并保留 contract;加入 metric scope/unit/method-version/status/age
直接借鉴会话目录、append-only 原始数据、manifest/capability/analysis按用户工作区存储,增加 schema migration、索引和保留策略
改造后借鉴场景、Marker、分位数、规则和基线修复多场景展开、动态刷新率阈值、比较键和样本不足状态
改造后借鉴Probe 的 HMAC/CRC/队列自监控与 dormant 降级作为独立增强 SDK,与无侵入模式分发布、分报告口径
不照搬单个 AppModel 承担设备、tunnel、签名、采集、分析和报告Perfowl 从第一版就拆分 domain actor/service,UI 只订阅会话状态
不照搬秒级 FPS 的低帧阈值作为 PerfDog 式流畅度秒级 FPS 仅用于趋势;FrameTime/Jank/BigJank 建立独立且可验证的数据源

获批后的建议推进顺序

P0
口径验证,而不是先搬代码
固定 iOS 16 / 17+ 真机,对 CPU、Physical Footprint、FPS、GPU 原值与 Xcode / PerfDog 做同场比较;先确定 GPU canonical unit 和采集自身开销。
P1
提取 Perfowl iOS Core
实现 DeviceRuntime、TunnelManager、ProcessSession、DVTCollector、EventWriter 五个边界;只接 CPU/内存/FPS/GPU 四个已校准主指标。
P2
场景、质量和回归
落地 Marker、多场景多轮次、分位数、完整度、动态阈值、可比较键和离线 HTML 报告。
P3
逐帧和深度诊断
单独验证 FrameTime/Jank 数据源;Probe 仅用于主线程、启动、业务网络和引擎协作,不取代系统最终呈现口径。
批准边界
本轮已完成调研和文档归档,没有将 Codesign4QC 性能代码复制到 Perfowl,也没有启动 P0 真机对照或产品开发。

代码与仓库证据

  1. /Users/itreenewbee/工作/代码/codesign4qc/tools/performance_collector.py — provider、sysmontap、Graphics、重绑与 v1 JSONL。
  2. MacApp/Sources/Codesign4QC/PerformanceCapturePipeline.swiftPerformanceEventRuntime.swift — 兼容输出、Schema v2、背压和质量计数。
  3. PerformanceMetrics.swiftModels.swiftPerformanceScenario.swift — 指标字典、统计、场景、规则和 verdict。
  4. PerformanceProbe.swiftPerformanceProbeAnalysis.swifttools/src/enhanced_runtime/ — 增强 Framework、协议与启动/显示/主线程/网络分析。
  5. docs/performance/stage-7a-test-report.mdstage-8-test-report.mdstage-10-test-report.md — 历史真机长会话、重启重绑和 Probe 传输证据。
  6. tests/test_performance_*.pyMacApp/Tests/Codesign4QCTests/*Performance*.swift — collector、fixture、事件压力、报告和可选真机回归。