Interroger des profils avec PerfettoSQL

Vous pouvez interroger les profils ProfilingManager à l'aide de PerfettoSQL et des modules de la bibliothèque standard Perfetto. Étant donné que ProfilingManager masque les traces système pour n'inclure que les données de processus de votre application, les requêtes de bibliothèque standards à l'échelle du système qui dépendent d'autres processus ne sont pas acceptées. Toutefois, la plupart des requêtes limitées à l'application et des modules de bibliothèque standards fonctionnent sans modification. Pour obtenir d'autres requêtes prêtes à l'emploi, consultez Analyser des traces Android.

Exemples de requêtes ProfilingManager

Utilisez les exemples de requêtes suivants directement ou comme modèles pour votre propre analyse PerfettoSQL.

Trouver les tranches les plus dupliquées

Les segments répétés indiquent souvent un travail redondant. Pour en savoir plus sur la syntaxe des fonctions, consultez Définir des fonctions dans PerfettoSQL. La requête suivante définit une fonction PerfettoSQL réutilisable qui recherche les segments correspondant à un modèle GLOB et les trie par fréquence :

-- You only need to call this once in the session to create or update the function
CREATE OR REPLACE PERFETTO FUNCTION find_duplicates(pattern STRING) RETURNS
TABLE(name STRING, count_slice LONG) AS SELECT name, COUNT(dur) as count_slice FROM slice WHERE name GLOB $pattern GROUP BY name HAVING COUNT(name) >= 2 ORDER BY count_slice DESC;

-- Subsequent calls can just use the function to find dupes
SELECT * FROM find_duplicates('*Text*')

Requêtes d'à-coups

Utilisez les requêtes suivantes pour identifier les images lentes ou saccadées dans une trace système.

Rechercher les frames lents

Cette requête recherche les images qui mettent plus de 16,6 ms (60 Hz) à s'afficher. Comme Perfetto stocke les durées des segments en nanosecondes, dur est comparé à 16660000 :

INCLUDE PERFETTO module android.frames.timeline;
SELECT * FROM android_frames WHERE dur > 16660000;

Rechercher les images à l'origine des à-coups

Cette requête utilise le module de chronologie des frames pour trouver les frames pour lesquels l'application n'a pas respecté le délai d'affichage en fonction de la fréquence d'actualisation de l'appareil :

INCLUDE PERFETTO module android.frames.timeline;
SELECT * FROM actual_frame_timeline_slice WHERE jank_type GLOB '*App Deadline Missed*';

Rechercher les objets les plus dupliqués

Dans une empreinte de la mémoire Java, cette requête renvoie les 100 premières classes avec au moins deux instances pour vous aider à repérer les doublons involontaires ou les opportunités de mise en cache :

INCLUDE PERFETTO MODULE android.memory.heap_graph.heap_graph_class_aggregation;

SELECT * FROM android_heap_graph_class_aggregation WHERE obj_count >= 2
ORDER BY obj_count DESC LIMIT 100

Latence de démarrage à froid

Cette requête estime le délai de démarrage à froid avant la première image (TTFF) en mesurant la durée entre bindApplication et la première tranche Choreographer#doFrame :

-- This function finds slices that match the given GLOB $pattern
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;

-- This function generates a slice that starts at $startSlicePattern and finishes at the slice matched by $endSlicePattern. If $inclusive is true, then the end slice dur will be added, otherwise, the end slice start time will be used.
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;

-- Using these functions we can estimate cold startup time by generating a slice between bindApplication and first frame.
SELECT * from generate_start_to_end_slices('bindApplication','*Choreographer#doFrame [0-9]*', true)