克魔助手
全部文章

没有 Mac,怎么给 iPhone 做性能分析

4 分钟阅读性能入门

我接触过的 iOS 团队里有一半不在 Mac 上。他们写代码,交给 CI,CI 在某个租来的 Mac 上打包。这套流程一直很顺,直到有人问一句“为什么在我手机上这么卡” —— 而答案偏偏藏在一个屋里没人有的机器上才能跑的工具里。

这篇讲的就是这种处境下实际有什么可用。

为什么显而易见的答案不成立

Instruments 是官方的性能分析器。它很好,同时有三个很容易被忽略的前提:

  1. 只在 macOS 上。
  2. 一般要有 Xcode 工程,至少要有个能附加上去的构建。
  3. 大多数有意思的 instrument,都希望你用一个开了调试的包。

第三条即使对有 Mac 的团队也是个隐性问题。Debug 包的优化级别不同、日志不同,有时候代码路径都不同。你分析它的时候,量的是一个没有任何用户在跑的程序。

手机自己就知道这些

工具的讨论里常常跳过一件事:iOS 本来就在测这些。系统会跟踪每个进程的 CPU、内存占用、GPU 利用率、帧呈现、网络字节数和能耗归因 —— 它不得不测,因为调度要用、内存压力下决定杀谁要用、“设置 → 电池”那一页也要用。

这些计数器通过设备自己的服务,向一台用户信任过的电脑开放。这条通道和“电脑给手机做备份”、“电脑给手机装包”是同一条。读它们不需要越狱、不需要在设备上常驻程序、不需要在你的 App 里加 SDK。

这样能拿到什么

连上设备,把范围收到某个 App,你能实时读到:

  • 每进程的 CPU(单核百分比)
  • 随时间变化的内存占用
  • GPU 利用率
  • 实际呈现的帧率
  • 网络收发字节数
  • 能耗影响

这不是 Instruments 的全部。没有分配调用树,没有精确到符号的时间剖析。但它足以回答绝大多数性能排查真正的起点问题:瓶颈在哪个资源上,什么时候?

而这通常就是全部问题

一份卡顿反馈,本质上不是在要一棵调用树,而是在问:你是 CPU 受限、GPU 受限,还是被什么阻塞了。这三种指向的修法完全不同,而图上的四条线就足以区分:

卡顿时刻 受限于
CPU 冲高、GPU 平 主线程上有活
GPU 冲高、CPU 平 渲染开销 —— 过度绘制、模糊、离屏渲染
内存跳升 一次大分配,通常是图片解码
什么都没动 阻塞在别处,或者在降频

知道自己在哪一行,就知道该去读哪部分代码。之后往往根本不需要调用树;确实需要的时候,你也已经知道该把哪一段交互交给那位有 Mac 的同事。

一个没人预料到会重要的点

在你手上那台设备上做分析,价值低于在用户手上那台设备上做分析。三年前的机型实际帧预算更紧、更早降频、电池容量已经衰减,而桌上的旗舰把这些全掩盖了。

由此带来的现实结果是:能在任意桌面系统上做性能分析,对没有 Mac 的团队来说不只是方便。它意味着你可以在屋里任何一台设备上分析 —— 测试同事的手机、售后备用机、抽屉里那台老机器 —— 而不是只能用配对在那台 Mac 上的两台设备。

一套可执行的流程

  1. 拿到投诉来源的那台设备,或者你支持的最旧机型。
  2. 让它凉下来。发烫的手机是另一台手机。
  3. 把范围收到你的 App。
  4. 采一段固定交互 —— 同一个列表、同样的距离、十秒。
  5. 找到下陷,读那一刻的其他曲线。
  6. 只改一件事,再采同一段交互。
  7. 对比。

第六步是最常被跳过的。单独一次采集只是一个数字;一次改动前后的两次采集,才是一个结论。

它替代不了什么

把边界说清楚:

  • 分配级分析。 内存趋势里看不出来的泄漏,还是需要堆分析工具。
  • 符号级 CPU 归因。 知道自己 CPU 受限,不等于知道是哪个函数。
  • 网络内容。 字节数不是请求,那是抓包工具的活。

设备级计数器做的事,是把“感觉有点卡”变成“在这台机型上,转场期间是 GPU 受限”。性能排查里绝大部分价值就在这一步,而它在你本来就坐着的这台电脑上就能做到。