Traces im Bulk analysieren

Wenn Sie mehrere Traces mit ProfilingManager erfasst haben, ist es nicht praktikabel, sie einzeln zu untersuchen, um Leistungsprobleme zu finden. Mit der Bulk-Trace-Analyse können Sie ein Dataset von Traces gleichzeitig abfragen, um:

  • Häufige Leistungsregressionen identifizieren
  • Statistische Verteilungen berechnen (z. B. P50-, P90-, P99-Latenz)
  • Muster in mehreren Traces finden.
  • Ausreißer-Traces finden, um Leistungsprobleme zu verstehen und zu beheben.

In diesem Abschnitt wird gezeigt, wie Sie mit dem Perfetto Python Batch Trace Processor Startmesswerte für eine Reihe lokal gespeicherter Traces analysieren und Ausreißer-Traces für eine genauere Analyse finden.

Abfrage entwerfen

Erstellen Sie zuerst eine PerfettoSQL-Abfrage, mit der der Messwert extrahiert wird, den Sie vergleichen möchten. Im folgenden Beispiel wird die app-gesteuerte Startlatenz von activityStart bis zum ersten gerenderten Frame (Choreographer#doFrame) gemessen, wie in Abbildung 1 dargestellt.

Eine Zeitachsenansicht eines Trace, in der die Dauer vom „activityStart“-Ereignis bis zum ersten „Choreographer#doFrame“-Ereignis hervorgehoben ist.
Abbildung 1. Trace-Abschnitt von activityStart bis zum ersten generierten Frame.
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)

Sie können die Abfrage in der Perfetto-Benutzeroberfläche ausführen und dann die Abfrageergebnisse verwenden, um einen Debug-Track (Abbildung 2) zu generieren und in der Zeitachse (Abbildung 3) zu visualisieren.

Bereich „Abfrageergebnisse“ der Perfetto-Benutzeroberfläche, in dem gezeigt wird, wie ein Debug-Track für eine Startabfrage erstellt wird.
Abbildung 2: Erstellen Sie einen Debug-Track für eine Startabfrage.
Eine Zeitachsenansicht in der Perfetto-Benutzeroberfläche, die einen generierten Debug-Track für eine Startabfrage zeigt.
Abbildung 3. Generierter Debug-Track für eine Startabfrage.

Python-Umgebung einrichten

Installieren Sie Python und die erforderlichen Bibliotheken auf Ihrem lokalen Computer:

pip install perfetto pandas plotly

Skript für die Bulk-Trace-Analyse erstellen

Im folgenden Beispielskript wird die Abfrage in mehreren Traces mit Perfettos Python BatchTraceProcessor ausgeführt.

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()

Script verstehen

Wenn Sie das Python-Skript ausführen, werden die folgenden Aktionen ausgeführt:

  1. Das Skript sucht in Ihrem lokalen Verzeichnis nach allen Perfetto-Traces mit dem Suffix .perfetto-trace und verwendet sie als Quell-Traces für die Analyse.
  2. Es wird eine Bulk-Trace-Abfrage ausgeführt, die den Teil der Startzeit berechnet, der der Zeit vom Trace-Slice activityStart bis zum ersten von Ihrer App generierten Frame entspricht.
  3. Die Latenz in Millisekunden wird mithilfe eines Violin-Plots dargestellt, um die Verteilung der Startzeiten zu visualisieren.

Ergebnisse interpretieren

Ein Violinendiagramm, das die Verteilung der abgefragten Startlatenzen zeigt.
Abbildung 4: Violindiagramm der abgefragten Startlatenzen.

Wenn Sie das Script ausführen, wird ein Violin-Diagramm mit einer bimodalen Verteilung mit zwei unterschiedlichen Latenzspitzen generiert (Abbildung 4). Bewegen Sie den Mauszeiger auf einzelne Datenpunkte im Diagramm, um den Dateinamen _path zu prüfen und die Traces der einzelnen Spitzenwerte zu vergleichen (Abbildung 5):

  • Traces mit hoher Latenz (rechter Peak): Wenn Sie einen Trace aus dieser Gruppe in der Perfetto-Benutzeroberfläche öffnen, wird ein zusätzlicher MyFlaggedFeature-Slice angezeigt, der während des Starts ausgeführt wird (Abbildung 6).
  • Traces mit niedriger Latenz (linker Peak): Wenn Sie einen Trace aus der schnelleren Gruppe öffnen, wird bestätigt, dass MyFlaggedFeature nicht vorhanden ist (Abbildung 7). Das deutet darauf hin, dass ein Funktions-Flag, das für eine Teilmenge von Nutzern aktiviert wurde, die Startregression verursacht hat.
Ein Diagramm, das einen Trace mit hoher Latenz hervorhebt.
Abbildung 5. Datenpunkt mit hoher Latenz in einem Violinendiagramm.
Ein Trace, der eine hohe Startlatenz aufgrund des MyFlaggedFeature-Slice hervorhebt.
Abbildung 6. Trace-Start mit hoher Latenz und einem zusätzlichen MyFlaggedFeature-Slice.
Ein Trace, der den Start mit niedriger Latenz ohne den Slice „MyFlaggedFeature“ hervorhebt.
Abbildung 7. Trace-Start mit niedriger Latenz.

In diesem Beispiel wird eine der vielen Möglichkeiten zur Verwendung der Bulk-Trace-Analyse gezeigt. Weitere Anwendungsfälle sind das Extrahieren von Statistiken aus dem Feld, um die Auswirkungen zu messen, das Erkennen von Regressionen und mehr.