Skip to content

StartupTiming 启动阶段指标 v4

定义

StartupTiming 同时保留两类不同含义的时间:

  1. CoreProfile App Launch Lifecycle:在被测 App 启动前启用 KDebug,按目标 PID/TID 还原启动总耗时与九类内部阶段。
  2. 外部观察:从 Perfowl 发送 launch 请求到轮询观察到进程/前台的耗时,带 polling 误差上界。

两类值的起终点不同,不互相替代。

metricID、scope、unit 与来源字段

metricID定义scopeunit来源字段
ios.process.startup.app_launch_total_msApp Launch 完整首尾耗时processmillisecondsSystem Interface begin → 与 Initial Frame begin 配对的 0x31CA0006
ios.process.startup.system_interface_msSystem Interface Initializationprocessmilliseconds0x1F07 code=130x2BDC code=4 arg0=10
ios.process.startup.static_runtime_msStatic Runtime Initializationprocessmilliseconds0x2BDC code=4 arg0=100x1F07 code=1 func=end
ios.process.startup.uikit_initialization_msUIKit Initializationprocessmilliseconds0x2B87 code=90 arg0=0x32code=21
ios.process.startup.uikit_scene_creation_ms所有 UIKit Scene Creation 完整 Span 之和processmilliseconds0x2B87 code=21/24/26/301/31323/25/300/312/12
ios.process.startup.will_finish_launching_mswillFinishLaunchingWithOptions()processmilliseconds0x2B87 code=2324
ios.process.startup.did_finish_launching_msdidFinishLaunchingWithOptions()processmilliseconds0x2B87 code=2526
ios.process.startup.scene_will_connect_mssceneWillConnectTo()processmilliseconds0x2B87 code=300301
ios.process.startup.scene_will_enter_foreground_mssceneWillEnterForeground()processmilliseconds0x2B87 code=312313
ios.process.startup.initial_frame_rendering_msInitial Frame Renderingprocessmilliseconds0x2B87 code=120x31CA0006
ios.process.startup.observed_running_mslaunch 请求到观察到进程processmillisecondslaunch.requested.rawobserved-running/rebound
ios.process.startup.foreground_ready_mslaunch 请求到观察到前台processmillisecondslaunch.requested.rawobserved-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 使用 lifecycle bm=1 配置。
  • 同名 phase 按线程内 stack 配对,重复 UIKit Scene Creation 各自保存;指标值为完整 Span 求和。
  • App Launch Total 用完整首尾锚点差,不将可能重叠的阶段相加;缺 System Interface begin 时保持 null,不把后半段局部耗时写成总耗时。
  • 0x31CA0006 必须闭合由 UIKit code=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 启动阶段分析结果

版本历史

  • v4(2026-09-06):新增 CoreProfile App Launch Total + 9 类阶段,启动前打开唯一 CoreProfile tap,并保留原有 Running/Foreground 外部观察;iOS 16/17/18 E4 映射结果以 update 段补入,跨版本门禁保持 partial。来源:方案结果
  • v3(2026-09-06):两项启动外部观察值进入实时 wire 与工作台。
  • v2(2026-09-05):起点前移到 launch 发送之前,加入单次非冷启动和身份核验。
  • v1(2026-09-05):建立两项启动观察耗时。

Perfowl · Performance Observer