ProfilingManager プロファイルをクエリする

ProfilingManager プロファイルのクエリは、通常の Perfetto プロファイルのクエリと似ています。そのため、プロファイルのクエリ方法については、PerfettoSQL のスタートガイドをご覧ください。

通常の Perfetto トレースと ProfilingManager トレースの重要な違いは、ProfilingManager トレースはトレース リダクターを通過することです。このリダクターは、プライバシー上の理由から、アプリに関係のない他のプロセスに関する情報を削除します。

Perfetto 標準ライブラリの一部のクエリは、編集されたトレースでは使用できません。これは、ProfilingManager が他のプロセスではなく、アプリのプロファイリング データのみを収集するためです。そのため、ProfilingManager で使用できるクエリは、ローカル Perfetto を使用して記録された完全なシステム プロファイルのクエリよりも少ないセットになります。

クエリ空間は縮小されますが、Perfetto 標準ライブラリの多くの PerfettoSQL クエリとテーブルはそのまま使用できるため、ぜひお試しください。

また、Android トレースの分析を確認して、変更なしで有用なパフォーマンス データを提供するすぐに使用できるクエリを見つけることもおすすめします。

ProfilingManager のサンプルクエリ

クエリの実行を簡素化するため、このセクションでは ProfilingManager で動作するクエリのリストを示します。これらのクエリは、直接使用することも、他のクエリを作成する際の例として使用することもできます。

最も重複しているスライスを見つける

このクエリは、トレース内の重複するスライスを検索し、出現頻度で並べ替えて、最も重複するスライスを最初に表示します。

重複した作業を見つけることは、トレースで不要な作業を見つける一般的な方法です。

-- 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*')

ジャンク クエリ

遅いフレームを見つける

このクエリは、アプリがフレームの生成に時間がかかりすぎているフレームを検索します。想定されるフレームレートは 60 Hz(16.6 ミリ秒)です。Perfetto テーブルのスライス期間はナノ秒単位で保存されるため、dur は 16,660,000 に設定されています。

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

ジャンクの原因となるフレームを見つける

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

このクエリは、アプリがフレームの生成に時間がかかりすぎるためにトレースでジャンクが発生する場所を特定するのに役立ちます。これは、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 個のオブジェクトを返します。これにより、複数回インスタンス化されたオブジェクトを見つけることができます。これにより、オブジェクトをキャッシュに保存する機会を見つけたり、意図しない重複を特定したりできます。

コールド スタートアップ レイテンシ

スタートアップをクエリすることもできます。このセクションでは、トレースでコールド スタート時間を推定するためのより複雑なクエリについて説明します。

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

このクエリは、起動時間を定義する 2 つのスライス(bindApplication(通常はコールド アプリの起動の開始時に見つかります)と最初の Choreographer#doFrame スライス(最初に生成されたフレーム))の間の時間を表すスライスを生成します。この指標は、コールド スタートアップの TTFF(最初のフレームまでの時間)を効果的に推定します。