外观
StartupTiming 启动阶段指标 v4
定义
StartupTiming 同时保留两类不同含义的时间:
- CoreProfile App Launch Lifecycle:在被测 App 启动前启用 KDebug,按目标 PID/TID 还原启动总耗时与九类内部阶段。
- 外部观察:从 Perfowl 发送 launch 请求到轮询观察到进程/前台的耗时,带 polling 误差上界。
两类值的起终点不同,不互相替代。
metricID、scope、unit 与来源字段
| metricID | 定义 | scope | unit | 来源字段 |
|---|---|---|---|---|
ios.process.startup.app_launch_total_ms | App Launch 完整首尾耗时 | process | milliseconds | System Interface begin → 与 Initial Frame begin 配对的 0x31CA0006 |
ios.process.startup.system_interface_ms | System Interface Initialization | process | milliseconds | 0x1F07 code=13 → 0x2BDC code=4 arg0=10 |
ios.process.startup.static_runtime_ms | Static Runtime Initialization | process | milliseconds | 0x2BDC code=4 arg0=10 → 0x1F07 code=1 func=end |
ios.process.startup.uikit_initialization_ms | UIKit Initialization | process | milliseconds | 0x2B87 code=90 arg0=0x32 → code=21 |
ios.process.startup.uikit_scene_creation_ms | 所有 UIKit Scene Creation 完整 Span 之和 | process | milliseconds | 0x2B87 code=21/24/26/301/313 → 23/25/300/312/12 |
ios.process.startup.will_finish_launching_ms | willFinishLaunchingWithOptions() | process | milliseconds | 0x2B87 code=23 → 24 |
ios.process.startup.did_finish_launching_ms | didFinishLaunchingWithOptions() | process | milliseconds | 0x2B87 code=25 → 26 |
ios.process.startup.scene_will_connect_ms | sceneWillConnectTo() | process | milliseconds | 0x2B87 code=300 → 301 |
ios.process.startup.scene_will_enter_foreground_ms | sceneWillEnterForeground() | process | milliseconds | 0x2B87 code=312 → 313 |
ios.process.startup.initial_frame_rendering_ms | Initial Frame Rendering | process | milliseconds | 0x2B87 code=12 → 0x31CA0006 |
ios.process.startup.observed_running_ms | launch 请求到观察到进程 | process | milliseconds | launch.requested.raw → observed-running/rebound |
ios.process.startup.foreground_ready_ms | launch 请求到观察到前台 | process | milliseconds | launch.requested.raw → observed-foreground |
Registry 事实源:MacApp/Sources/PerfowlCore/PerformanceModels.swift。CoreProfile 源为 dvt.coreprofilesessiontap.kdebug,外部观察源为 lifecycle-observer。
计算、窗口、差分/聚合与取整
启动阶段算法 core-profile-app-lifecycle.candidate.v2:
text
timestampNs = floor(machTicks × timebaseNumer / timebaseDenom)
spanDurationMs = (endTimestampNs - startTimestampNs) / 1,000,000
phaseTotalMs = sum(同 phase 的所有完整 Span durationMs)
appLaunchTotalMs = initialFrameEndTimestampNs - systemInterfaceBeginTimestampNs- 窗口是单次
controlled-cold-launch的单一 PID/generation,不跨启动聚合;CoreProfile 必须先于 launch ACK-ready,tap 使用 lifecyclebm=1配置。 - 同名 phase 按线程内 stack 配对,重复 UIKit Scene Creation 各自保存;指标值为完整 Span 求和。
- App Launch Total 用完整首尾锚点差,不将可能重叠的阶段相加;缺 System Interface begin 时保持 null,不把后半段局部耗时写成总耗时。
0x31CA0006必须闭合由 UIKitcode=12打开的 Initial Frame Rendering;同进程更早出现但没有对应 begin 的终点只计入 ignored,不能形成 App Launch Total。- 跨 CPU/分块记录先按 Mach timestamp 重排;相同 timestamp 用原始到达序号稳定排序,同一 transition 先处理 END 再处理 BEGIN。
- 计算保留 Double,不取整;UI 只格式化小数。
外部观察算法仍为 startup-observation.candidate.v2:
text
elapsedMs = (terminalHostMonotonicNs - launchRequestedHostMonotonicNs) / 1,000,000
pollingErrorUpperBoundMs = max(pollIntervalSeconds) × 1,000质量语义
candidate:PID 归因通过、首尾闭合、所有已接受 Span 完整;私有协议映射尚未完成跨版本数值对齐。partial:至少有受接受 Span/marker,但缺 BEGIN/END 或 Initial Frame 未闭合;只写最终 Session 报告,不作为一次性实时完成事件提前发布。missing:未绑定目标 PID,或目标 lifecycle 事件未观察到。unsupported-schema:RAW v2 header、Mach timebase 或时间范围违反冻结契约。- 缺值是 null/—,不写 0;未闭合 Span 不参与时长。
当前校准状态
- E1:py-ios-device
2.4.26源码已确认machTimeInfo → coreprofilesessiontap setConfig/start → ProcessControl launch → KDebug RAW v2协议链及旧阶段映射。该映射不是 Apple 公开稳定契约。 - E2:Perfowl 增量解码、PID/TID 映射、重复 Span、缺失门禁、双次回放 hash、唯一 CoreProfile adapter、final partial wire 与 Swift 9 阶段 UI 已通过自动化验证;Python 146/146、Swift 80/80。
- E4 partial:iOS 17/18 最终二进制均确认 CoreProfile launch 前 ready、目标身份 verified、drop=0、停止/finalize/wire 全链;但两台最终 Session 分别有 139/430 个未知 lifecycle 事件,9 类旧映射没有形成完整阶段,最终质量均为
missing、App Launch Total 为 null。 - E4 replay:iOS 16 历史 raw 可形成 4 个 Span/3 类阶段;iOS 17 历史 raw 可形成 2 个 Span/2 类阶段;两者均因缺完整开始锚点保持
partial,不输出局部总耗时。
因此产品入口为“条件可用”:采集和质量链已接通,只有当前系统/App 的事件能被有证据映射并完整配对时才显示阶段值。iOS 17/18 新 code 在完成可控 Fixture + Instruments/xctrace 同窗映射前继续 fail-closed。验收来源:P2 CoreProfile 启动阶段分析结果。