השאילתות של פרופילי ProfilingManager דומות לשאילתות של פרופילי Perfetto רגילים. לכן, מומלץ לעיין במאמר תחילת העבודה עם PerfettoSQL כדי ללמוד יותר על שאילתת פרופילים.
הבדל חשוב בין עקבות רגילות של Perfetto לבין עקבות של ProfilingManager הוא שעקבות של ProfilingManager עוברות דרך כלי צנזור. מטעמי פרטיות, הכלי הזה מסיר מידע על תהליכים אחרים שלא קשורים לאפליקציה שלכם.
בעקבות שצונזרו, אי אפשר להשתמש בחלק מהשאילתות מהספרייה הסטנדרטית של Perfetto. הסיבה לכך היא ש-ProfilingManager אוסף רק נתוני פרופיל בשביל האפליקציה שלכם, ולא בשביל תהליכים אחרים. כתוצאה מכך, מספר השאילתות שאפשר להשתמש בהן עם ProfilingManager מצומצם יותר מהמספר שזמין בפרופילי מערכת מלאים, שתועדו באמצעות Perfetto מקומי.
למרות שמספר השאילתות מצומצם, עדיין אפשר להשתמש בהרבה שאילתות וטבלאות של PerfettoSQL מתוך הספרייה הסטנדרטית של Perfetto כמו שהן, ולכן מומלץ לנסות אותן.
מומלץ גם לעיין במאמר ניתוח עקבות ב-Android כדי למצוא שאילתות מוכנות לשימוש שמספקות נתוני ביצועים שימושיים ללא צורך בשינוי.
שאילתות לדוגמה של ProfilingManager
כדי שתהליך השאילתות יהיה קל יותר, בקטע הזה מופיעה רשימה של שאילתות שפועלות עם ProfilingManager. אפשר להשתמש בשאילתות האלה ישירות או כדוגמאות ליצירת שאילתות אחרות.
איך מוצאים את הפרוסות (slice) הכי משוכפלות
השאילתה הזו מוצאת פרוסות שחוזרות על עצמן בעקבות וממיינת אותן לפי התדירות שבה הן מופיעות, כך שהפרוסות הכי משוכפלות מוצגות ראשונות.
כשאותה עבודה מופיעה יותר מפעם אחת בעקבות, זה לרוב מצביע על עבודה מיותרת.
-- 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*')
שאילתות שקשורות לבעיות בממשק (jank)
איך מוצאים פריימים איטיים
השאילתה הזו מוצאת פריימים שבהם לאפליקציה לוקח יותר מדי זמן ליצור פריימים, בהנחה שקצב הפריימים הצפוי הוא 60Hz (16.6 אלפיות השנייה). הערך של dur הוא 16,660,000 כי משך הזמן של הפרוסות בטבלאות של Perfetto מאוחסן בננו-שניות.
INCLUDE PERFETTO module android.frames.timeline;
SELECT * FROM android_frames WHERE dur > 16660000;
חיפוש פריימים שגורמים לבעיות בממשק (jank)
INCLUDE PERFETTO module android.frames.timeline;
SELECT * FROM actual_frame_timeline_slice WHERE jank_type = 'App Deadline Missed';
השאילתה הזו שימושית כדי למצוא מיקומים שבהם מתרחשות בעיות בממשק (jank) בנתוני המעקב, כי לאפליקציה לוקח יותר מדי זמן ליצור פריים. זה בעצם אומר ששרשור ה-UI נכשל ביצירת פריים. במקרים קיצוניים, יכול להיות שההודעה הזו תופיע לפני ANR.
חיפוש האובייקטים שיש להם הכי הרבה כפילויות
אפשר גם לשלוח שאילתות לפרופילים שקשורים לזיכרון, כמו תמונות מצב של הזיכרון, כדי לבצע ניתוחים מורכבים יותר שלו.
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
השאילתה הזו מחזירה את 100 האובייקטים שיש להם הכי הרבה כפילויות. כך תוכלו למצוא אובייקטים שנוצרו כמה פעמים ולשמור אותם במטמון או פשוט למצוא כפילויות לא מכוונות.
זמן הטעינה של הפעלה מההתחלה (cold startup)
אפשר גם להריץ שאילתות על הפעלות. בקטע הזה מוסברת שאילתה מורכבת יותר שעוזרת להעריך את זמן ההפעלה מההתחלה (cold startup) בעקבות.
-- 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)
השאילתה הזו יוצרת פרוסה (slice) שמייצגת את הזמן שחלף בין שתי פרוסות שמגדירות את זמן ההפעלה: bindApplication (בדרך כלל נמצאת בתחילת הפעלה קרה של האפליקציה) והפרוסה הראשונה Choreographer#doFrame (הפריים הראשון שנוצר). המדד הזה מעריך בצורה יעילה את זמן ההפעלה מההתחלה (cold startup) עד להצגת הפריים הראשון (TTFF).