일괄 추적 분석

ProfilingManager를 사용하여 여러 트레이스를 수집한 후 성능 문제를 찾기 위해 개별적으로 탐색하는 것은 비실용적입니다. 대량 추적 분석을 사용하면 추적 데이터 세트를 동시에 쿼리하여 다음 작업을 할 수 있습니다.

  • 일반적인 성능 저하를 식별합니다.
  • 통계 분포 (예: P50, P90, P99 지연 시간)를 계산합니다.
  • 여러 트레이스에서 패턴을 찾습니다.
  • 이상치 트레이스를 찾아 성능 문제를 파악하고 디버그합니다.

이 섹션에서는 Perfetto Python 배치 트레이스 프로세서를 사용하여 로컬에 저장된 트레이스 집합에서 시작 측정항목을 분석하고 자세한 분석을 위해 이상치 트레이스를 찾는 방법을 보여줍니다.

쿼리 설계

일괄 분석을 실행하는 첫 번째 단계는 PerfettoSQL 쿼리를 만드는 것입니다.

이 섹션에서는 앱 시작 지연 시간을 측정하는 쿼리의 예를 보여줍니다. 특히 activityStart부터 생성된 첫 번째 프레임 (Choreographer#doFrame 슬라이스의 첫 번째 발생)까지의 기간을 측정하여 앱의 제어 범위 내에 있는 앱 시작 지연 시간을 측정할 수 있습니다. 그림 1은 쿼리할 섹션을 보여줍니다.

활동 시작 이벤트부터 첫 번째 Choreographer#doFrame 이벤트까지의 기간을 강조 표시하는 트레이스의 타임라인 뷰
그림 1. `activityStart` 에서 생성된 첫 번째 프레임까지의 섹션을 추적합니다.
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)

Perfetto UI 내에서 쿼리를 실행한 다음 쿼리 결과를 사용하여 디버그 트랙을 생성하고 (그림 2) 타임라인 내에서 시각화할 수 있습니다 (그림 3).

시작 쿼리의 디버그 트랙을 만드는 방법을 보여주는 Perfetto UI 스크린샷
그림 2. 스타트업 쿼리의 디버그 트랙을 만듭니다.
시작 쿼리에 대해 생성된 디버그 트랙을 보여주는 Perfetto UI의 타임라인 뷰
그림 3. 시작 쿼리에 대해 생성된 디버그 트랙입니다.

Python 환경 설정

로컬 머신에 Python 및 필수 라이브러리를 설치합니다.

pip install perfetto pandas plotly

대량 추적 분석 스크립트 만들기

다음 샘플 스크립트는 Perfetto의 Python BatchTraceProcessor를 사용하여 여러 트레이스에서 쿼리를 실행합니다.

from perfetto.batch_trace_processor import BatchTraceProcessor
import glob
import plotly.express as px

traces = glob.glob('*.perfetto-trace')

if __name__ == '__main__':
    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)

        violin = px.violin(df, x='dur_ms', hover_data='_path', title='startup time', points='all')
        violin.show()

스크립트 이해

Python 스크립트를 실행하면 다음 작업을 수행합니다.

  1. 이 스크립트는 로컬 디렉터리에서 .perfetto-trace로 끝나는 모든 Perfetto 트레이스를 검색하고 이를 분석의 소스 트레이스로 사용합니다.
  2. activityStart 트레이스 슬라이스부터 앱에서 생성된 첫 번째 프레임까지의 시간에 해당하는 시작 시간의 하위 집합을 계산하는 대량 트레이스 쿼리를 실행합니다.
  3. 바이올린 플롯을 사용하여 시작 시간의 분포를 시각화하여 지연 시간을 밀리초 단위로 표시합니다.

결과 해석

쿼리된 시작 지연 시간의 분포를 보여주는 바이올린 플롯
그림 4. 쿼리된 시작 지연 시간의 바이올린 플롯

스크립트를 실행하면 스크립트에서 플롯을 생성합니다. 이 경우 플롯에는 두 개의 뚜렷한 피크가 있는 이봉 분포가 표시됩니다 (그림 4).

그런 다음 두 모집단의 차이를 찾습니다. 이를 통해 개별 트레이스를 더 자세히 검사할 수 있습니다. 이 예에서는 데이터 포인트 (지연 시간) 위로 마우스를 가져가면 트레이스 파일 이름을 식별할 수 있도록 플롯이 설정되어 있습니다. 그런 다음 지연 시간이 긴 그룹에 속하는 트레이스 중 하나를 열 수 있습니다.

지연 시간이 긴 그룹에서 트레이스를 열면 시작 중에 실행되는 MyFlaggedFeature라는 추가 슬라이스가 표시됩니다(그림 6). 반대로 지연 시간이 짧은 집단 (가장 왼쪽의 피크)에서 트레이스를 선택하면 동일한 슬라이스가 없음을 확인할 수 있습니다 (그림 7). 이 비교를 통해 일부 사용자에게 사용 설정된 특정 기능 플래그가 회귀를 트리거함을 알 수 있습니다.

지연 시간이 높은 트레이스를 강조 표시한 플롯
그림 5. 바이올린 플롯의 지연 시간이 긴 데이터 포인트
MyFlaggedFeature 슬라이스로 인해 지연 시간이 높은 시작을 강조 표시하는 트레이스
그림 6. `MyFlaggedFeature` 슬라이스가 추가된 긴 지연 시간 트레이스 시작
MyFlaggedFeature 슬라이스 없이 짧은 지연 시간으로 시작하는 것을 강조 표시하는 트레이스
그림 7. 짧은 지연 시간 트레이스 시작

이 예시에서는 대량 추적 분석을 사용할 수 있는 여러 방법 중 하나를 보여줍니다. 다른 사용 사례로는 필드에서 통계를 추출하여 영향을 측정하고, 회귀를 감지하는 등이 있습니다.