PerfDog export audit · iOS
PerfDog 导出样本与 Perfowl 基座能力差距
本页只做数据盘点、代码对照和补齐设计,不进入功能开发。结论基于用户提供的 iOS Excel 导出样本、PerfDog 官方帮助中心、用户补充的 2023 年博客园指标文章、Perfowl 当前提交 9fb707f 以及既有真机冒烟证据;应用名、设备名、Bundle ID 和源文件路径均未写入文档。
Executive conclusion
先给结论:链路已通,PerfDog 级指标层尚未形成
当前真正端到端
FPS、App CPU、Physical Footprint 已经走通 Sidecar → Swift → Session → Mac 实时曲线,但都仍是 Experimental。FPS/GPU 是前台设备渲染管线口径,不是严格的目标进程独占口径。
已有源、尚未产品化
Resident Memory、线程数、上下文切换、唤醒、磁盘读写速率、Renderer/Tiler/Device GPU 等已有 DVT 数据源或 Sidecar 输出;其中大部分未进入 PerformanceSample、Metric Registry、UI 和报告。
关键空白
逐帧 Frame Time、Smooth/1% Low/Jank/BigJank/Stutter、System/分核 CPU、网络、可用内存、热、分类 Energy、截图/Marker、区间统计和报告回放尚未形成完整能力。
不能直接宣称对齐
字段同名不代表口径相同。Perfowl 当前的磁盘/唤醒/切换是每秒速率,PerfDog 导出列未说明是区间增量还是速率;Memory、GPU、Energy 也必须取得定义并同场比对。
Workbook inventory
这份 PerfDog 样本实际包含什么
| 区域 | 字段 | 样本观察 |
|---|---|---|
| 设备信息 | Device Name、Device Type、Product Type、OS、CPU Type/Arch/CoreNum/Freq、GPU Type、CollectMode | 10 个静态字段;CollectMode=0 的含义在文件中没有说明。 |
| Stat | FPS/FrameTime 分布、Jank 频率、Memory/CPU 阈值、Network 10 分钟折算 | 29 个汇总字段;包含 Avg/Std/Var/Median、每小时或每 10 分钟归一值。 |
| Data_v4 | 时间/标签、帧体验、CPU、内存、网络、磁盘、GPU、热、调度、Energy、截图 | 44 列、53 行;时间严格每 1,000 ms 一个点。 |
| @FrameInfo | time、FTime、label | 1,845 帧;从 -992 ms 预滚到 51,991 ms,前 19 帧尚未进入 label1。 |
Official rules + sample replay
官方口径与样本复算已经可以分层
Jank、BigJank、SmallJank、1% Low、Stutter、Drop(FPS) 和 MedRange(FPS) 已从官方页面取得定义;样本计算用于验证导出实现。TinyJank 与 Smooth 的完整公式仍未公开,继续标记为未知。
| 指标 | 官方定义 / 复算 | 吻合情况 | 边界 |
|---|---|---|---|
| Avg(FPS) | 1000 / mean(1,845 个 FTime) | 34.8114 → 导出 34.81 | 说明整体 FPS 汇总直接受逐帧 FTime 支撑。 |
| Drop(FPS) | 相邻两个 FPS 点下降超过 8 帧的次数,再按小时折算。 | 官方定义已确认 | 仍需确认等于 8、缺点和测试末尾的处理。 |
| MedRange(FPS) | FPS 落在中位数 ±20% 范围内的占比。 | 官方定义已确认 | 仍需确认边界是否包含、0 FPS 与缺值处理。 |
| SmallJank | 当前 FTime > 前三帧均值×2 且 > 41.66ms | 官方定义已确认 | 首三帧、动态刷新率和等号边界待 Fixture 固化。 |
| Jank | 当前 FTime > 前三帧均值×2 且 > 83.33ms | 官方页面常写约 84ms | 实现必须固化精确常量和边界,不使用 UI 四舍五入值替代。 |
| BigJank | 当前 FTime > 前三帧均值×2 且 > 125ms | 官方定义已确认 | 同一帧是否同时计入多类事件需用导出样本验证。 |
| 1% Low(FPS) | 1000 / mean(耗时最长的 1% 帧) | 19 帧复算 1.1652 → 导出 1.17 | 官方公式与样本吻合;ceil/floor 和短 Session 规则仍需确认。 |
| Stutter | Σ Jank time / 测试总时长 | 官方专项页已确认 | Jank time 的精确扣除基线、重叠事件和空帧区间仍需样本消歧。 |
| Tiny/Small/Jank/BigJank(/10min) | 事件总数 / 52s × 600 | 24/24/18/16 → 276.9/276.9/207.7/184.6 | 归一化分母使用时间跨度 52s,不是 53 个采样点。 |
| FTime>=100[%] | 30 / 1845 × 100 | 1.626% → 导出 1.6% | 阈值可复算,帧筛选范围仍要跨样本确认。 |
| Delta(FTime)>100ms[/h] | 23 个正向相邻差值 / 52s × 3600 | 1592.3077 → 导出 1592.3 | 该样本支持“正向差值”,不是绝对差值。 |
| Network KB/10min | Avg(KB/s) × 600 | Recv+Send 179.78 × 600 → 107,866.18 | 原始值保留精度高于 Excel 显示精度。 |
Capability levels
本次对照使用的状态分级
| 级别 | 定义 | 能否对外承诺 |
|---|---|---|
| A · 基础链路已通 | Sidecar 采到、Swift 承接、Session 保留、UI 可见 | 仅以 Experimental 名称展示,校准后才能升级。 |
| B · 数据源已接 | Sidecar 能输出或原始文件可保存,但产品模型/UI/统计不完整 | 内部调试可用,不能当作完整产品指标。 |
| C · 候选入口存在 | DVT/xctrace 有候选源,当前代码未接,或代码字段未真正请求 | 先做字段探针和真机验证。 |
| D · 当前缺失/语义未知 | 缺原始事件、算法或 PerfDog 定义 | 保持 Unsupported,不用近似值或 0 填充。 |
Field-by-field matrix
PerfDog → Perfowl 字段对照
| PerfDog 字段 | 当前 Perfowl 状态 | 已知数据源 / 当前去向 | 补齐动作与验收 |
|---|---|---|---|
| Num / time / absTime | A · 已有 | sequence、UTC timestamp、monotonicNs;Session append-only | 建立统一 Session 零点与设备/Host 时钟偏差模型,再导出 PerfDog 风格相对毫秒。 |
| label / Notes | D · 未实现 | 界面只有固定 Scene 01 文案,没有 Marker 事件 | 增加 Marker/场景/备注事件,记录 start/end/instant 和统一时间戳。 |
| FPS | A · 基础链路已通 | DVT Graphics → framesPerSecond → PerformanceSample → UI | 校准 60/90/120Hz、前后台、静止和多进程;明确 foreground-device scope。iOS Wi-Fi 默认只承诺 60 FPS,高帧率增强需 iOS 17+、开发者签名和系统 HUD。 |
| FTime(@FrameInfo) | D · 关键缺失 | 当前 Graphics 只有秒级 FPS,没有逐帧事件 | 建立 FramePipeline:先验证 DVT/py-ios-device 协议线索,再用 xctrace Display/Frame Lifetimes/Hitches 做真值老师;原始帧必须可回放。 |
| Smooth | D · 公式未知 | 官方只给游戏/视频 <8、App 滑动 <20 的建议值,未给计算公式 | 索取 Tooltip 与多组导出;在逐帧源确定后以黑盒样本验证,公式未确认前保持 Unsupported。 |
| Drop(FPS) / MedRange(FPS) | D · 定义已知、尚未实现 | 官方已给下降 >8 帧与中位数 ±20% 规则;当前无秒级分析引擎 | 实现版本化算法,并用缺点、边界值、静止/后台场景确认窗口与分母。 |
| 1%Low(FPS) | D · 定义已知、尚未实现 | 官方为最慢 1% 帧的平均 FTime 取倒数;样本支持 ceil(1%) 候选 | 用不同长度、刷新率和无帧区间确认取整/窗口规则,再进入 AnalysisEngine。 |
| SmallJank / Jank / BigJank | D · 定义已知、缺逐帧源 | 动态条件均为当前帧 > 前三帧均值 2 倍;静态阈值分别为 41.66/83.33/125ms | 取得稳定 Display FrameTime,构造已知卡顿 Fixture;固化首帧、等号、刷新率、后台和事件重叠规则。 |
| TinyJank | D · 定义不完整 | 官方只说明高帧率下用于识别极小卡顿,未给完整公式 | 继续保持 Unsupported;等待官方公式或足够黑盒样本,禁止自行近似。 |
| Stutter[%] | D · 定义已知、尚未实现 | 官方为 Σ Jank time / 测试总时长 | 确认 Jank time 的精确计算、重叠事件、0 FPS 和长帧处理,再版本化实现。 |
| AppCPU[%] | A · 基础链路已通 | DVT sysmontap cpuUsage → Swift → UI;官方同时出现“除核心数”和“iOS 未规范化”表述 | 与 PerfDog/Xcode 同场确认单核/多核口径;原值与 normalized 值分开保存。 |
| TotalCPU[%] | C · 候选源已被请求但丢弃 | Sidecar 配置已经请求 sysmonSystemAttributes,但迭代器只保留 Processes | 先保存 System 原始区块和字段字典,再映射总 CPU;不能直接从 AppCPU 推算。 |
| CPUUsage0–5[%] | C · 候选源待探针 | 可能存在于 DVT System 属性;当前没有承接 | 真机记录动态属性名、核心数量与离线/降频状态;按设备核心拓扑输出数组而非固定 6 列。 |
| Memory / XcodeMemory[MB] | A · 候选映射已通 | 官方定义 Memory=Footprint、XcodeMemory=Xcode Debug Gauge;physicalFootprint 已端到端,样本中两列完全相同 | 与 Xcode Gauge 同场确认当前字段映射;两列分 metricID 保存,即使某版本数值相同也不合并语义。 |
| RealMemory[MB] | B · 源已接、未展示 | 官方定义为 Instruments 实际物理内存;memResidentSize → residentMemory → PerformanceSample,UI 未展示 | 用 Instruments 同场确认 resident size 映射;加入 Registry/报告并保留原始 bytes。 |
| VirtualMemory[MB] | C · 代码占位未生效 | payload 有 virtualMemory,但 PROCESS_ATTRIBUTES 没有请求 memVirtualSize | 动态确认字段存在后加入请求与 Swift 模型;大地址空间值只作诊断,不作为泄漏结论。 |
| AvailableMemory[MB] | C · 系统源待接 | 当前未读取 System 区块 | 从 sysmonSystemAttributes 或受支持的设备信息源取原值,验证与 PerfDog 的可用/空闲定义。 |
| Send / Recv[KB/s] | C · 入口存在、未实现 | pymobiledevice3 DVT NetworkMonitor 候选;当前官方客户端说明为整机流量,2023 第三方文章写目标进程 | 默认按 device scope 设计并通过“目标 App/其他 App 分流”实验消歧;若 PID 归属不可证明,不对外显示进程流量。 |
| ReadDiskBytes / WriteDiskBytes | B · 源已接、口径不同 | sysmontap 累计计数已转换为 bytes/s;Swift 能解码但 PerformanceSample/UI 未保留 | 同时保存 raw counter、interval delta、bytes/s;向 PerfDog 确认导出列是哪一种,再做对照。 |
| Render / Tiler / Device[%] | B · 源已接、承接不完整 | DVT Graphics 三项均进入 Sidecar;Swift 只保留 Device,UI 未显示 GPU | 补 Swift/Registry/Sample/UI;三项继续标 foreground-device,并做 PerfDog 同场误差和字段单位校准。 |
| BTemp[℃] | D · 未实现 | 官方定义为电池温度;当前没有稳定温度源,样本也只有 2/53 点 | 验证权限、采样频率与缺值策略;找不到稳定无侵入源则保持 Unsupported。 |
| ThermalStatus | C · 候选源待验证 | DVT Energy/notification 或 xctrace Thermal State 候选;当前没有映射 | 索取数值枚举表;保存 raw code + display level,不能把样本中的 10 猜成系统 nominal/serious。 |
| Wakeups / CSwitch | B · 源已接、口径待对齐 | intWakeups 与 ctxSwitch 已转成每秒速率;Swift 可解码但 Sample/UI 未保留 | 保留累计原值和差分速率,确认 PerfDog 列是 1 秒增量还是速率;补 Registry/报告。 |
| Battery Current / Voltage / Power | D · 模式化能力缺失 | 官方要求 Wi-Fi 模式、约 20 秒采样;USB 充电情况下不具参考意义 | 单独建立 battery capability 和低频时间轴;USB 下明确 unavailable,不用 Energy 分数冒充物理量。 |
| CPU/GPU/Network/Location/Display/Overhead Energy | D · 分类能力缺失 | 官方对齐 Xcode Energy Impact,Total ≤270/270–1000/>1000 对应 Low/High/Very High;sysmontap powerScore 不能直接等价 | 验证 DVT EnergyMonitor 字段;xctrace Energy Log 只作增强诊断。保存分类分数与 Total,和 Current/Voltage/Power 严格分开。 |
| ScreenShot | C · 能力入口存在、未接 | DVT Screenshot 候选;当前 Session 没有媒体目录与时间关联 | 实现手动/Marker/低频截图,记录 captureAt 与最近样本偏差;本样本只有文件名,需原图包才能验收。 |
Statistics and report gap
Stat 区域不是“多加几个平均值”,而是独立分析层
当前能直接算
- 已有采样的 Avg/Min/Max/Std/Var/Median/P50/P90/P95/P99。
- 基于 Session 时间跨度的阈值占比和每小时/每 10 分钟折算。
- CPU/Memory/FPS/GPU 等共享时间轴的区间统计。
当前还不能算
- 所有依赖逐帧 FTime 的体验指标。
- 依赖准确源口径的 System CPU、Network、Energy、Thermal 汇总。
- 场景/Marker 区间、截图关联和多进程聚合。
Perfowl 当前 Session 主要保存原始/规范化事件和质量计数,没有 AnalysisEngine 与报告模型。补齐时应保持 Raw Event → Derived Metric(version) → Report,禁止把派生结果覆盖回原始数据;这样 PerfDog 算法理解变化后可以离线重算。
Recommended completion route
建议补齐顺序
| 批次 | 目标 | 具体内容 | 完成门槛 |
|---|---|---|---|
| P0 原始数据保真 | 不丢已有能力 | 动态字段清单;保存 Processes + System 原始区块;累计 counter 与派生 rate 并存;扩展 Swift Codable/Metric Registry | 每个输出值可追到 source/key/unit/scope/sample interval;Session 可离线重算。 |
| P0 现有源产品化 | 快速覆盖基础资源 | Resident/线程/磁盘/Wakeup/CSwitch/Render/Tiler/Device GPU 进入 Sample、UI、统计 | 真实前台 User App 连续 10–30 分钟;与 PerfDog/Xcode 同场误差有记录。 |
| P0 FramePipeline | 解决最大产品差距 | 逐帧事件、刷新率、FrameTime、Drop、MedRange、1% Low、Small/Jank/BigJank、Stutter;TinyJank/Smooth 保持 Hold;xctrace 做增强真值 | 60/120Hz + 静止/滚动/动画/人工卡顿 Fixture 可复现、可解释。 |
| P1 System 与 Network | 补 Total/分核 CPU、Available Memory、收发速率 | System 区块 adapter;NetworkMonitor;PID/连接归属与 generation 重置 | 上传/下载/短长连接/前后台场景覆盖;未知流量显示 missing,不显示 0。 |
| P1 Marker/截图/报告 | 形成可复查测试 | Marker/Notes、媒体目录、同步十字线、区间统计、历史回放、HTML/Excel 导出 | 任一异常点能回到场景、截图、原始值和派生公式版本。 |
| P2 Thermal/Energy | 补相对诊断 | DVT EnergyMonitor/Thermal 探针;xctrace Energy/Thermal 增强;分类模型 | 定义与单位有证据、开销可接受;物理量与相对分数严格分开。 |
Information request
需要用户协助收集的 PerfDog 资料
官方资料已经补齐大部分主体定义;下面材料用于确认边界、采集 scope 和当前付费客户端实际行为。完成第 1–3 项后,Frame/Jank 才能从“定义已知”进入“可校准实现”。
- 仍缺的定义/Tooltip:Smooth、TinyJank 完整公式,ThermalStatus 数值枚举,Read/WriteDiskBytes 是累计值、区间增量还是速率。
- 原始导出完整包:Excel 同目录的 43 张 jpg、PerfDog 报告页面截图、若客户端支持则导出原始 Session/工程文件。当前 Excel 只有文件名,无法验证截图时钟和画面关联。
- 采集配置截图:付费客户端中 iOS CollectMode、采样频率、截图频率、FPS/Jank 模式、能耗模式、USB/Wi-Fi、是否启用多进程的全部开关。
- 四组固定场景:同一设备分别采集 60 秒静止、匀速滚动、持续动画、每 2 秒人工阻塞;每组提供 Excel + 报告截图。最好同时录一份 xctrace Display/Frame Lifetimes/Hitches。
- 高刷新率样本:一台 120Hz 设备关闭/开启 Low Power Mode,重复滚动与人工卡顿,确认动态刷新率、1%Low 和 Jank 阈值。
- 资源专项样本:目标 App 与其他 App 分别纯上传/下载,再补磁盘读写、CPU 满载、GPU 动画、定位开启/关闭、前后台切换,用于确认 Network scope、Energy/Thermal 归属和缺值含义。
- 多进程与商店 App:选含 WebView/Extension 的 App,提供 PerfDog 的进程选择和聚合界面截图,确认导出是主进程还是进程组。
Decision point
下一次批准前的停止点
本轮结论足以确定:下一阶段不应直接做云端或堆更多图表,而应先做 P0 原始数据保真 + 现有 DVT 字段完整承接;FramePipeline 的主体公式已经明确,但开发仍需逐帧数据源探针和固定场景对照样本。当前未修改 Collector、Swift 模型或 UI。
Evidence ledger
证据边界
| 证据 | 本次用途 | 不能证明 |
|---|---|---|
| PerfDog 官方帮助中心 | 指标主体定义、模式限制、Service 映射和产品范围 | 未公开私有算法与当前客户端所有边界行为。 |
| 2023 博客园指标文章 | 历史指标交叉参考与 Network scope 冲突识别 | 第三方资料不能覆盖当前官方说明。 |
| 用户提供的 PerfDog Excel | 字段、样本频率、缺值、帧序列和可复算统计 | 跨版本定义、所有采集模式、字段单位来源。 |
| Perfowl 当前源码 @ 9fb707f | Sidecar 请求字段、Swift 承接、Session/UI 去向 | 未运行代码路径的真机可用性和指标准确度。 |
| 既有 iOS 16 真机冒烟摘要 | DVT 连续流、部分进程指标与 Graphics 可达 | 真实前台 User App 长时稳定、iOS 17+、与 PerfDog 误差。 |
| 本次数值复算 | 提出算法候选和后续 Fixture 断言 | PerfDog 私有实现或所有边界条件。 |