功能介绍
开发应用或元服务过程中,如果遇到卡顿、加载耗时等性能问题,开发者通常会关注相关函数执行的耗时情况。DevEco Profiler提供的Time场景分析任务,可在应用/元服务运行时,展示热点区域内基于CPU和进程耗时分析的调用栈情况,并提供跳转至相关代码的能力,使开发者更便捷地进行代码优化。
Time模板支持的泳道包括:User Trace、ArkTS Callstack、Callstack、Energy。本文介绍User Trace、ArkTS Callstack、Callstack泳道,Energy泳道的详细信息请参考能耗诊断:Energy分析。
函数耗时分析及优化
在设备连接完成后,可按照如下方法查看耗时分析结果:
- 构建应用前请参考模块级build-profile.json5文件,增加strip字段并赋值为false,不移除当前模块.so文件中的符号表、调试信息。采集函数栈解析符号需要附带符号表信息,无符号表信息可能采集不到函数名称,或ArkTS Callstack泳道无法关联到Native调用栈,因此请按照下图进行配置。

- 创建Time任务并录制相关数据,操作方法可参考性能问题定位:深度录制。Time分析任务支持在录制前单击
指定要录制的泳道: 说明
- 单击任意泳道名称后方的
可将其置顶。 - Release版本的so库构建时,默认优化等级为-O2,编译器会对代码进行函数内联、寄存器分配、指令重排等优化,可能导致函数调用栈缺失、局部变量被优化、运行时序与源码不一致,从而造成录制数据不完整。可以在CMakeLists.txt中配置编译优化等级为-O0,采集完整的数据。
- 在ArkTS Callstack泳道和ArkTS Callstack子泳道上长按鼠标左键并拖拽,框选要分析的时间段。Details区域会显示所选时间段内的函数栈耗时分布情况,Heaviest Stack区域会展示出Details区域选择节点所处的耗时最长的完整调用栈。函数栈耗时分布有三种展现方式:调用树(默认展示方式)、火焰图、冰锥图。
- 在调用树中,“Weight”字段表示当前函数的总执行时间,“Self”字段表示函数自身的执行时间,两者之差为当前函数所调用的子函数执行时间之和,“Average Duration”字段表示函数自身的平均执行时间,“Category”字段表示函数调用类型。
- 打开页面下方的Flame Chart开关,函数调用栈将以火焰图的形式展示,横轴表示函数的执行时长,纵轴表示调用栈的深度。

- 在ArkTS Callstack子泳道或Callstack子泳道上点击Unfold CallStack按钮,可以在泳道图区域将函数调用栈以冰锥图的形式展示,调用栈的先后顺序与实际调用时序保持一致。

- 在Callstack泳道上长按鼠标左键并拖拽,框选要分析的时间段。
- Summary区域展示框选时段内,所有Native线程的CPU占用率的峰值、谷值、平均值。
- Callstack区域展示框选时段内,所有Native线程的函数热点。

- 将鼠标悬浮到节点,显示以此节点为根节点,点击添加面包屑。添加面包屑后,该节点成为根节点,耗时占比为100%,子节点的耗时占比相对于该节点重新计算。

- 在Callstack子泳道上长按鼠标左键并拖拽,框选要展示分析的时间段。
- Top Down页签显示所选时间段内的函数栈耗时分布情况,Heaviest Stack区域会展示出Details区域选择节点所处的耗时最长的完整调用栈。
- Bottom UP页签显示函数列表,展开任一函数节点可查看其调用方及每个调用方的耗时。

- (可选)在详情区中双击需要优化的节点(例如耗时超过预期),可快速跳转至对应工程源码,为开发者节省定位代码路径的时间。
说明
- Release应用暂不支持跳转到用户侧Native代码。
- 静态链接的系统库无法支持源码跳转。如libunwind.a,在编译过程中该系统库会以静态链接的方式集成。该系统库的符号信息在调用栈中会被识别成用户侧定义的函数,实际上无法跳转到源码。
多实例函数热点分析
在应用开发过程中,可能存在一些耗时操作,则需要引入Worker线程或者TaskPool任务池来协同处理。这些线程也可能会像主线程一样存在性能问题,所以需要同时对这些子线程进行性能调优。其中,主线程以及每一个Work线程或者TaskPool工作线程,都会对应一个方舟实例,通过连接这些方舟实例,开启性能采样,从而可以获取更全面的采样信息。
- ArkTS Callstack父泳道内可以看到被选择进程的CPU使用率,框选后展示此时段内录制到的所有方舟实例的函数调用栈信息。
- ArkTS Callstack子泳道框选后展示此时段内录制到的该方舟实例的函数调用栈信息。

离线符号解析
DevEco Profiler提供离线符号解析能力,基于携带符号表信息的so库进行分析,可把符号地址解析为具体函数名称,便于定位函数位置。
对于有so库路径和偏移地址的采样数据,如图所示,通过导入对应的携带符号表信息的so库进行解析,补充release so库中缺失的符号表信息(包括系统so库,用户自编译的so库,三方库)。

您可以通过点击工具栏
按钮,导入包含debug信息的so库。
说明
- 离线导入携带符号表信息的so库,需要严格保证与Release版本的so库保持同一优化等级(如-O1, -O2, -O3等)。可以在CMakeLists.txt文件中查看或配置编译优化等级。
- 离线导入携带符号表信息的so库,需要尽可能与Release版本的so库编译选项保持一致,防止so库起始地址不一致,影响解析正确性。

查询自定义打点信息
相较于异步调度,DevEco Profiler当前基于采样分析的Time任务更善于分析同步性能问题。如开发者需要分析异步调度延时等问题,可先在ArkTS代码中进行自定义打点,当应用/元服务在Time分析过程中触发打点后,DevEco Profiler会将这些打点的Trace数据解析后,以任务方块形式呈现在User Trace泳道中。
单击User Trace泳道的“options”下拉列表,可以设置子泳道是按照Task Name维度还是Thread ID维度显示。

- 展开User Trace泳道,在子泳道上长按鼠标左键并拖拽,框选要展示分析的时间段,获取该时间段内的用户打点信息。
- Statistics区域:显示当前任务泳道在所选时间段内的打点任务统计信息,包括任务的名称、同一任务执行的次数、平均持续时长、最长持续时间和最短持续时间。通过这些统计信息,开发者可直观地了解打点任务的执行频率、持续时间偏差等,方便定位。
- User Trace区域:将所选时间段内的所有任务都一一列举出来,包括任务的ID、名称、起始/结束时间、持续时长等。

- 单击User Trace子泳道中的任意一个任务块,Details区域将展示该任务块的详细信息。
