Wysyłanie zapytań do profili ProfilingManager

Wykonywanie zapytań dotyczących profili ProfilingManager jest podobne do wykonywania zapytań dotyczących zwykłych profili Perfetto. Dlatego zapoznaj się z artykułem Pierwsze kroki z PerfettoSQL, aby dowiedzieć się, jak wysyłać zapytania do profili.

Ważną różnicą między zwykłymi logami Perfetto a logami ProfilingManager jest to, że logi ProfilingManager przechodzą przez procesor redagowania logów. Ze względu na ochronę prywatności to narzędzie usuwa informacje o innych procesach niezwiązanych z Twoją aplikacją.

Niektórych zapytań ze standardowej biblioteki Perfetto nie można używać w przypadku śladów z usuniętymi danymi. Dzieje się tak, ponieważ ProfilingManager zbiera dane profilowania tylko dla Twojej aplikacji, a nie dla innych procesów. W rezultacie zapytania, których możesz używać z ProfilingManager, stanowią mniejszy zbiór niż zapytania dotyczące pełnych profili systemowych zarejestrowanych za pomocą lokalnego narzędzia Perfetto.

Mimo że przestrzeń zapytań jest ograniczona, nadal możesz używać wielu zapytań i tabel PerfettoSQL z biblioteki standardowej Perfetto w niezmienionej postaci, dlatego zachęcamy do ich wypróbowania.

Zalecamy też zapoznanie się z artykułem Analizowanie logów czasu Androida, aby znaleźć gotowe do użycia zapytania, które dostarczają przydatnych danych o skuteczności bez konieczności wprowadzania zmian.

Przykładowe zapytania dotyczące ProfilingManager

Aby uprościć proces tworzenia zapytań, w tej sekcji znajdziesz listę zapytań, które działają z ProfilingManager. Możesz używać tych zapytań bezpośrednio lub jako przykładów do tworzenia innych zapytań.

Znajdowanie najbardziej zduplikowanych wycinków

To zapytanie znajduje powtarzające się wycinki w śladzie i sortuje je według częstotliwości występowania, wyświetlając najpierw te, które powtarzają się najczęściej.

Znajdowanie powielonych zadań to powszechny sposób na znalezienie niepotrzebnych zadań w śladzie.

-- You only need to call this once in the session to create the function
DROP TABLE IF EXISTS find_duplicates;
CREATE 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*')

Zapytania dotyczące zacinania się

Znajdowanie spowolnionych klatek

To zapytanie znajduje klatki, których wygenerowanie zajmuje aplikacji zbyt dużo czasu, przy założeniu, że oczekiwana liczba klatek na sekundę wynosi 60 Hz (16,6 ms). Wartość dur jest ustawiona na 16 660 000, ponieważ czas trwania wycinków w tabelach Perfetto jest przechowywany w nanosekundach.

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

Znajdowanie klatek powodujących zacinanie się

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

To zapytanie jest przydatne do znajdowania lokalizacji, w których w śladzie występuje zacinanie, ponieważ aplikacja zbyt długo generuje klatkę. Oznacza to, że wątkowi UI nie udało się wygenerować klatki. W skrajnych przypadkach może to poprzedzać błąd ANR.

Znajdowanie najbardziej zduplikowanych obiektów

Możesz też wysyłać zapytania do profili związanych z pamięcią, takich jak zrzuty sterty, aby przeprowadzać bardziej złożone analizy pamięci.

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

To zapytanie zwraca 100 najczęściej powielanych obiektów. Może to pomóc w znalezieniu obiektów, które są tworzone wielokrotnie, co może ujawnić możliwości ich buforowania lub zidentyfikować niezamierzone duplikaty.

Czas oczekiwania na uruchomienie „na zimno”

Możesz też wysyłać zapytania dotyczące startupów. W tej sekcji znajdziesz bardziej rozbudowane zapytanie do oszacowania czasu uruchomienia „na zimno” w logu czasu.

-- This function finds slices that match the given GLOB $pattern
CREATE OR REPLACE 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)

To zapytanie generuje wycinek, który reprezentuje czas między 2 wycinkami definiującymi czas uruchamiania: bindApplication (zwykle na początku uruchamiania aplikacji na zimno) i pierwszym wycinkiem Choreographer#doFrame (pierwsza wygenerowana klatka). Te dane skutecznie szacują czas do pierwszej klatki (TTFF) podczas uruchomienia „na zimno”.