Depois de coletar vários traces usando o ProfilingManager, analisá-los
individualmente para encontrar problemas de desempenho se torna impraticável. A análise de traces em massa permite consultar um conjunto de dados de traces simultaneamente para:
- Identificar regressões de desempenho comuns.
- Calcule distribuições estatísticas (por exemplo, latência P50, P90, P99).
- Encontrar padrões em vários traces.
- Encontre traces atípicos para entender e depurar problemas de desempenho.
Nesta seção, mostramos como usar o processador de rastreamento em lote do Perfetto para Python para analisar métricas de inicialização em um conjunto de rastreamentos armazenados localmente e localizar rastreamentos atípicos para uma análise mais detalhada.
Criar a consulta
A primeira etapa para realizar uma análise em massa é criar uma consulta PerfettoSQL.
Nesta seção, apresentamos um exemplo de consulta que mede a latência de inicialização do app.
Especificamente, é possível medir a duração de activityStart até o primeiro
frame gerado (a primeira ocorrência da fração Choreographer#doFrame) para
medir a latência de inicialização do app que está sob o controle dele. A Figura 1 mostra
a seção para consulta.
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)
É possível executar a consulta na interface do Perfetto e usar os resultados para gerar uma faixa de depuração (Figura 2) e visualizá-la na linha do tempo (Figura 3).
Configure o ambiente Python
Instale o Python na máquina local e as bibliotecas necessárias:
pip install perfetto pandas plotly
Criar o script de análise de trace em massa
O script de amostra a seguir executa a consulta em vários traces usando o
BatchTraceProcessor do Python do Perfetto.
from perfetto.batch_trace_processor import BatchTraceProcessor
import glob
import plotly.express as px
# Collect all trace files in the local directory
traces = glob.glob('*.perfetto-trace')
if not traces:
print("No .perfetto-trace files found in the current directory.")
exit(1)
if __name__ == '__main__':
# Process all traces in parallel to aggregate metrics across runs
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)
# Plot the distribution of startup times, tracking trace file paths on
# hover
violin = px.violin(df, x='dur_ms', hover_data='_path', title='startup time', points='all')
violin.show()
Noções básicas sobre o script
Quando você executa o script Python, ele realiza as seguintes ações:
- O script pesquisa no diretório local todos os traces do Perfetto com o sufixo
.perfetto-tracee os usa como traces de origem para análise. - Ele executa uma consulta de trace em massa que calcula o subconjunto do tempo de inicialização
correspondente ao tempo entre o fragmento de trace
activityStarte o primeiro frame gerado pelo app. - Ele mostra a latência em milissegundos usando um gráfico de violino para visualizar a distribuição dos tempos de inicialização.
Interprete os resultados
Depois de executar o script, ele gera um gráfico. Nesse caso, o gráfico mostra uma distribuição bimodal com dois picos distintos (Figura 4).
Em seguida, encontre a diferença entre as duas populações. Isso ajuda a examinar traces individuais em mais detalhes. Neste exemplo, o gráfico está configurado para que, ao passar o cursor sobre os pontos de dados (latências), seja possível identificar os nomes dos arquivos de trace. Em seguida, abra um dos traces que fazem parte do grupo de alta latência.
Ao abrir um trace do grupo de alta latência (Figura 5), você vai encontrar uma
fração extra chamada MyFlaggedFeature em execução durante a inicialização (Figura 6).
Por outro lado, selecionar um rastro da população de menor latência (o pico mais à esquerda) confirma a ausência dessa mesma fração (Figura 7). Essa comparação
indica que uma flag de recurso específica, ativada para um subconjunto de usuários, aciona
a regressão.
Este exemplo demonstra uma das muitas maneiras de usar a análise de trace em massa. Outros casos de uso incluem extrair estatísticas do campo para avaliar o impacto, detectar regressões e muito mais.