Analyser des traces de manière groupée

Une fois que vous avez collecté plusieurs traces à l'aide de ProfilingManager, il devient difficile de les explorer individuellement pour identifier les problèmes de performances. L'analyse groupée des traces vous permet d'interroger simultanément un ensemble de données de traces pour :

  • Identifier les régressions de performances courantes
  • Calculer les distributions statistiques (par exemple, la latence P50, P90, P99)
  • Recherchez des modèles dans plusieurs traces.
  • Recherchez les traces aberrantes pour comprendre et déboguer les problèmes de performances.

Cette section explique comment utiliser le processeur de traces par lot Perfetto Python pour analyser les métriques de démarrage sur un ensemble de traces stockées localement et localiser les traces aberrantes pour une analyse plus approfondie.

Concevoir la requête

Commencez par créer une requête PerfettoSQL qui extrait la métrique que vous souhaitez comparer. L'exemple suivant mesure la latence au démarrage contrôlée par l'application, de activityStart à la première image affichée (Choreographer#doFrame), comme illustré dans la figure 1.

Vue chronologique d'une trace, mettant en évidence la durée entre l'événement activityStart et le premier événement Choreographer#doFrame.
Figure 1. Section de trace de activityStart à la première image générée.
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)

Vous pouvez exécuter la requête dans l'interface utilisateur de Perfetto, puis utiliser les résultats de la requête pour générer une trace de débogage (figure 2) et la visualiser dans la chronologie (figure 3).

Panneau des résultats de la requête de l'UI Perfetto montrant comment créer une piste de débogage pour une requête de démarrage.
Figure 2. Créez une trace de débogage pour une requête de démarrage.
Vue chronologique dans l'interface utilisateur de Perfetto montrant une trace de débogage générée pour une requête de démarrage.
Figure 3 : Trace de débogage générée pour une requête de démarrage.

Configurer l'environnement Python

Installez Python sur votre ordinateur local, ainsi que les bibliothèques requises :

pip install perfetto pandas plotly

Créer le script d'analyse groupée des traces

L'exemple de script suivant exécute la requête dans plusieurs traces à l'aide de BatchTraceProcessor de Python de Perfetto.

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

Comprendre le script

Lorsque vous exécutez le script Python, il effectue les actions suivantes :

  1. Le script recherche dans votre répertoire local toutes les traces Perfetto avec le suffixe .perfetto-trace et les utilise comme traces sources pour l'analyse.
  2. Il exécute une requête de trace groupée qui calcule le sous-ensemble du temps de démarrage correspondant au temps écoulé entre la section de trace activityStart et la première image générée par votre application.
  3. Il trace la latence en millisecondes à l'aide d'un diagramme en violon pour visualiser la distribution des temps de démarrage.

Interprétation des résultats

Un diagramme en violon montrant la distribution des latences de démarrage interrogées.
Figure 4. Diagramme en violon des latences de démarrage interrogées.

L'exécution du script génère un diagramme en violon montrant une distribution bimodale avec deux pics de latence distincts (figure 4). Pointez sur des points de données individuels dans le graphique pour inspecter le nom de fichier _path et comparer les traces de chaque pic (figure 5) :

  • Traces à latence élevée (pic de droite) : l'ouverture d'une trace de ce groupe dans l'UI de Perfetto révèle une tranche MyFlaggedFeature supplémentaire exécutée au démarrage (figure 6).
  • Traces à faible latence (pic de gauche) : l'ouverture d'une trace du groupe plus rapide confirme que MyFlaggedFeature est absent (figure 7), ce qui indique qu'un flag de fonctionnalité activé pour un sous-ensemble d'utilisateurs a provoqué la régression du démarrage.
Un graphique mettant en évidence une trace à latence élevée.
Figure 5. Point de données à latence élevée dans un diagramme en violon.
Trace mettant en évidence un démarrage à latence élevée en raison de la tranche MyFlaggedFeature.
Figure 6. Démarrage de la trace à latence élevée avec un segment MyFlaggedFeature supplémentaire.
Trace mettant en évidence un démarrage à faible latence sans la tranche MyFlaggedFeature.
Figure 7. Démarrage de la trace à faible latence.

Cet exemple illustre l'une des nombreuses façons d'utiliser l'analyse de trace groupée. D'autres cas d'utilisation incluent l'extraction de statistiques sur le terrain pour évaluer l'impact, la détection des régressions, etc.