批量分析跟踪记录

使用 ProfilingManager 收集多个跟踪记录后,逐个探索这些跟踪记录以查找性能问题变得不切实际。通过批量跟踪分析,您可以同时查询跟踪记录数据集,以便:

  • 识别常见的性能回归。
  • 计算统计分布(例如 P50、P90、P99 延迟时间)。
  • 在多个跟踪记录中查找模式。
  • 查找离群跟踪记录,以了解和调试性能问题。

本部分演示了如何使用 Perfetto Python 批量轨迹处理器分析一组本地存储的轨迹中的启动指标,并找出离群轨迹以进行更深入的分析。

设计查询

首先,创建一个 PerfettoSQL 查询,用于提取要比较的指标。以下示例测量了从 activityStart 到第一个渲染帧 (Choreographer#doFrame) 的应用控制的启动延迟时间,如图 1 所示。

轨迹的时间轴视图,突出显示了从 activityStart 事件到第一个 Choreographer#doFrame 事件的时长。
图 1. 从 activityStart 到生成的第一个帧的跟踪记录部分。
CREATE OR REPLACE PERFETTO FUNCTION find_slices(pattern STRING) RETURNS
TABLE (name STRING, ts LONG, dur LONG) AS
SELECT name,ts,dur FROM slice WHERE name GLOB $pattern;

CREATE OR REPLACE PERFETTO FUNCTION generate_start_to_end_slices(startSlicePattern STRING, endSlicePattern STRING, inclusive BOOL) RETURNS
TABLE(name STRING, ts LONG, dur LONG) AS
SELECT name, ts, MIN(startToEndDur) as dur
FROM
  (SELECT S.name as name, S.ts as ts, E.ts + IIF($inclusive, E.dur, 0) - S.ts as startToEndDur
  FROM find_slices($startSlicePattern) as S CROSS JOIN find_slices($endSlicePattern) as E
  WHERE startToEndDur > 0)
GROUP BY name, ts;

SELECT ts,name,dur from generate_start_to_end_slices('activityStart','*Choreographer#doFrame [0-9]*', true)

您可以在 Perfetto 界面中执行查询,然后使用查询结果生成调试轨迹(图 2),并在时间轴中直观呈现(图 3)。

Perfetto 界面查询结果面板,显示如何为启动查询创建调试轨道。
图 2. 为启动查询创建调试轨道。
Perfetto 界面中的时间轴视图,其中显示了为启动查询生成的调试轨迹。
图 3. 为启动查询生成了调试跟踪记录。

设置 Python 环境

在本地机器上安装 Python 及其所需的库:

pip install perfetto pandas plotly

创建批量跟踪记录分析脚本

以下示例脚本使用 Perfetto 的 Python BatchTraceProcessor 在多个跟踪记录中执行查询。

from perfetto.batch_trace_processor import BatchTraceProcessor
import glob
import plotly.express as px

# Collect all trace files in the local directory
traces = glob.glob('*.perfetto-trace')

if not traces:
    print("No .perfetto-trace files found in the current directory.")
    exit(1)

if __name__ == '__main__':
    # Process all traces in parallel to aggregate metrics across runs
    with BatchTraceProcessor(traces) as btp:
        query = """
        CREATE OR REPLACE PERFETTO FUNCTION find_slices(pattern STRING) RETURNS
        TABLE (name STRING, ts LONG, dur LONG) AS
        SELECT name,ts,dur FROM slice WHERE name GLOB $pattern;

        CREATE OR REPLACE PERFETTO FUNCTION generate_start_to_end_slices(startSlicePattern STRING, endSlicePattern STRING, inclusive BOOL) RETURNS
        TABLE(name STRING, ts LONG, dur LONG) AS
        SELECT name, ts, MIN(startToEndDur) as dur
        FROM
          (SELECT S.name as name, S.ts as ts, E.ts + IIF($inclusive, E.dur, 0) - S.ts as startToEndDur
          FROM find_slices($startSlicePattern) as S CROSS JOIN find_slices($endSlicePattern) as E
          WHERE startToEndDur > 0)
        GROUP BY name, ts;

        SELECT ts,name,dur / 1000000 as dur_ms from generate_start_to_end_slices('activityStart','*Choreographer#doFrame [0-9]*', true)
        """
        df = btp.query_and_flatten(query)
        # Plot the distribution of startup times, tracking trace file paths on
        # hover
        violin = px.violin(df, x='dur_ms', hover_data='_path', title='startup time', points='all')
        violin.show()

了解脚本

运行 Python 脚本时,它会执行以下操作:

  1. 该脚本会在本地目录中搜索后缀为 .perfetto-trace 的所有 Perfetto 轨迹,并将其用作分析的源轨迹。
  2. 它会运行批量跟踪查询,计算启动时间中对应于从 activityStart 跟踪切片到应用生成的第一帧的时间的子集。
  3. 它使用小提琴图绘制以毫秒为单位的延迟时间,以直观呈现启动时间的分布情况。

解释结果

一个小提琴图,显示查询到的启动延迟时间的分布情况。
图 4. 查询到的启动延迟时间的小提琴图。

运行该脚本会生成一个小提琴图,显示具有两个明显延迟高峰的双峰分布(图 4)。将鼠标悬停在图中的各个数据点上,以检查 _path 文件名并比较每个峰值的轨迹(图 5):

  • 高延迟跟踪记录(右侧峰值):在 Perfetto 界面中打开此组中的跟踪记录会显示在启动期间运行的额外 MyFlaggedFeature 切片(图 6)。
  • 低延迟跟踪记录(左侧峰值):打开较快组中的跟踪记录,确认 MyFlaggedFeature 不存在(图 7),这表明为一部分用户启用的功能标志导致了启动性能下降。
突出显示高延迟跟踪记录的图。
图 5. 小提琴图中的高延迟数据点。
突出显示因 MyFlaggedFeature 切片而导致的高延迟启动的跟踪记录。
图 6. 高延迟跟踪启动,其中包含额外的 MyFlaggedFeature 切片。
突出显示不含 MyFlaggedFeature 切片的低延迟启动的跟踪记录。
图 7. 低延迟跟踪启动。

此示例演示了使用批量跟踪分析的众多方法之一。 其他应用场景包括从现场提取统计信息以衡量影响、检测回归等。