macOS-Trace: Otimização Autônoma de Desempenho de Aplicativos
macOS-Trace é um mecanismo de otimização de desempenho em loop fechado para aplicativos macOS nativos (SwiftUI, AppKit, Metal, CoreAudio, WebKit e binários nativos).
O objetivo é eliminar a interação manual com a GUI do Instruments. Um agente de IA pode diagnosticar de forma autônoma, localizar gargalos, implementar alterações de código, re-testar com benchmarking diferencial e iterar até que as metas de desempenho sejam verificadas com dados empíricos.
+-------------------------------------------------------------------------+
| O Loop de Otimização Autônoma |
| |
| 1. Alinhamento de Metas ──> 2. Criação de Perfil Diagnóstico ──> 3. Correção de Código Direcionada |
| ^ │ |
| │ ▼ |
| └────── Iterar se a Meta Não For Atingida <── 4. Verificação de Re-teste |
+-------------------------------------------------------------------------+
Fase 1: Alinhamento de Metas com o Usuário (Questionário Pré-voo)
Antes de modificar o código ou coletar rastreamentos, o agente deve se alinhar com o usuário sobre as metas de otimização e os critérios de sucesso.
Ferramenta Modal vs Interação por Chat
- Se sua plataforma de agente fornecer uma ferramenta de questionário/modal interativa (por exemplo,
ask_question, diálogos de entrada ou listas de opções selecionáveis), invoque-a para apresentar essas escolhas de forma limpa ao usuário. - Se nenhuma ferramenta modal estiver disponível, pergunte diretamente ao usuário na conversa com opções estruturadas e valores recomendados concretos.
Perguntas a Fazer ao Usuário
- Objetivo Principal de Otimização:
- Opção A: Reduzir utilização da CPU, consumo de energia e throttling térmico.
- Opção B: Reduzir a pegada de memória, picos de alocação transitória ou eliminar vazamentos.
- Opção C: Eliminar engasgos de frames da UI e quedas de quadros de animação (Hitches).
- Opção D: Acelerar o tempo de inicialização a frio do aplicativo.
- Metas Específicas de Desempenho (Fornecer Padrões Recomendados):
- Metas de CPU / Energia:
- Linha de Base Ociosa: < 20 M/s instruções, Impacto na CPU < 0,5.
- Carga de Trabalho Ativa: < 100 M/s instruções (ou especificar: reduzir em 30% - 50%).
- Metas de Memória:
- RAM Residente Máxima: Limitar a < 150 MB (utilitários/áudio) ou < 300 MB (mídia/UI rica).
- Taxa de Eventos de Alocação: < 500 eventos/s durante execução em estado estável.
- Vazamentos de Memória: Exatamente 0 vazamentos persistentes.
- Metas de Suavidade da UI:
- Taxa de Engasgos (Hitch Ratio): < 5,0 ms/s (aceitável), < 1,0 ms/s (fluido/sem quadros perdidos).
- Metas de Tempo de Inicialização:
- Tempo para o Primeiro Frame: < 400 ms (excelente), < 800 ms (aceitável).
- Metas de CPU / Energia:
- Cenário de Benchmark do Usuário:
- Pergunte ao usuário qual tela, interação ou carga de trabalho específica deve ser usada como benchmark.
Uma vez que as metas sejam confirmadas, prossiga para a Fase 2.
Escopo e Pré-requisitos
- Plataforma alvo: Aplicativos desktop macOS nativos apenas (SwiftUI, AppKit, Metal, CoreAudio / AVAudioEngine, visualizações host WebKit, executáveis CLI nativos). Não suporta simuladores iOS, dispositivos móveis remotos ou aplicativos web externos apenas em navegador.
- Ferramentas Xcode: Requer macOS 12+ e Xcode completo ou Ferramentas de Linha de Comando do Xcode (
xcode-select -p,xcrun xctrace version). - Python: Python 3.8+ (pré-instalado no macOS; zero dependências pip externas).
- Permissões de processo: Builds de depuração ou binários com a permissão
get-task-allowsão necessários para--attach <PID>sob o Hardened Runtime.
Regras para Agentes
Siga estas regras inegociáveis durante a criação automatizada de perfil:
- Estabeleça uma linha de base primeiro: Nunca grave apenas a carga de trabalho ativa. Sempre capture uma linha de base ociosa (aplicativo aberto em primeiro plano, carga de trabalho pausada) antes de gravar o estado ativo. Calcule:
Delta = Ativo - Linha de Base. - Verifique o estado alvo antes de gravar: Confirme que o processo existe usando
pgrep -x <ProcessName>e que o recurso alvo está em execução ativa durante a janela de gravação. - Mantenha a janela em primeiro plano: o macOS limita a renderização e os links de exibição (
NSWindowOcclusionState) para janelas ocultas ou minimizadas. Uma janela oculta produzirá leituras falsamente baixas de GPU e CPU. - Use parâmetros de teste iguais: Compare execuções com durações de amostra idênticas (padrão:
60s), escalas de exibição idênticas, tamanhos de janela idênticos e dados de entrada de teste idênticos. Nunca compare um build de Depuração com um build de Lançamento. - Sem dependências Python de terceiros: Todos os scripts incluídos (
scripts/compare_elements.py,scripts/parse_power.py,scripts/top_categories.py) usam apenas a biblioteca padrão do Python 3. Não instale pacotes pip. - Salve as saídas em
/tmp/macos-traces/: Armazene todos os bundles.tracee exportações.xmlem/tmp/macos-traces/com nomes de arquivo carimbados com data e tag do cenário. - Proteja o orçamento de contexto da conversa: Arquivos de rastreamento e documentos XML exportados brutos podem ter dezenas ou centenas de megabytes. Nunca despeje saídas
.tracebrutas, árvores de chamada completas ou XML de Alocações não analisado no contexto da conversa do agente. Sempre use os scripts Python incluídos para transmitir, filtrar, classificar e resumir os dados antes de ler. - Concentre-se nos gargalos primários: Não espalhe micro-otimizações em dezenas de funções de utilitário inocentes. Crie o perfil primeiro para confirmar o contribuidor dominante (por exemplo, instâncias de superfície redundantes, reavaliações de timer de alta frequência, E/S não armazenada em buffer) e concentre os esforços de otimização exclusivamente nessa causa raiz.
- Nunca altere silenciosamente a UI, efeitos visuais ou comportamento principal: Se um gargalo de desempenho envolver fidelidade visual (como materiais de desfoque/vidro, animações de quadros, sombras, transições de layout) ou comportamento essencial do software:
- Não remova ou rebaixe unilateralmente o recurso visual.
- Peça formalmente permissão ao usuário primeiro (usando um prompt interativo ou mensagem de chat explícita).
- Articule claramente o tradeoff: Descreva a mudança visual antes e depois, explique por que o recurso consome recursos e apresente o ganho de desempenho esperado concreto (por exemplo, "Desabilitar o desfoque dinâmico de fundo reduzirá o impacto da GPU ativa de 1,5 para 0,2 e economizará ~50 M/s instruções da CPU").
- Limpe os artefatos de gravação: Cada gravação
xctraceescreve rastreamentos de kernel transitórios de vários GB (instruments*.ktrace) e um cache da CLI do Instruments (C/com.apple.dt.InstrumentsCLI) na pasta temporária do sistema ($TMPDIR).scripts/run_trace.shos remove automaticamente na saída (tanto em caso de sucesso quanto de falha). Ao executarxctracediretamente, limpe-os você mesmo antes de concluir:Nunca termine uma sessão deixando centenas de GB de dados de gravação transitórios para trás.find "${TMPDIR:-/tmp}" -maxdepth 1 -type f -name 'instruments*.ktrace' -delete 2>/dev/null || true
O Protocolo de Otimização em 4 Fases
Fase 2: Criação de Perfil Diagnóstico e Atribuição
Antes de escrever código, meça o estado atual e isole a causa raiz:
# 1. Verificação pré-voo: o aplicativo deve estar em execução com sua janela visível
APP_NAME="YourApp"
pgrep -x "$APP_NAME" || { echo "[ERROR] $APP_NAME não está em execução. Inicie-o primeiro."; exit 1; }
# SKILL_DIR = diretório instalado deste skill (ajuste se instalado em outro local)
SKILL_DIR="$HOME/.claude/skills/macos-trace"
# 2. Grave a linha de base ociosa de 60s (carga de trabalho pausada, janela visível)
# run_trace.sh resolve o nome do processo para um PID por conta própria
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "01-baseline"
# 3. Acione a carga de trabalho no aplicativo, grave o estado ativo
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "02-pre-opt"
# 4. Calcule o delta pré-otimização
python3 "$SKILL_DIR/scripts/compare_elements.py" \
/tmp/macos-traces/01-baseline-power.xml:"Linha de Base Ociosa" \
/tmp/macos-traces/02-pre-opt-power.xml:"Ativo Pré-Otimização"
Use os modelos especializados para atribuir o gargalo:
- Execute
--template timepara isolar funções quentes na árvore de chamada. - Execute
--template alloccomscripts/top_categories.pypara identificar alocações excessivas. - Execute
--template hitchesdurante a rolagem para isolar atrasos de renderização vs. commit.
Fase 3: Modificação de Código Direcionada
Aplique correções cirúrgicas mínimas com base nos resultados:
- Threads de áudio em tempo real alocando memória heap? Substitua por buffers circulares lock-free pré-alocados.
- IPC do WebKit saturado? Reduza a frequência de atualizações de estado e mude para animações CSS transform.
- Fragment shader do Metal com sobreposição em Retina? Adicione dimensionamento dinâmico de resolução ou pause loops de renderização fora da tela.
- Picos de decodificação de imagem de alta resolução? Adote o downsampling
CGImageSourceCreateThumbnailAtIndex.
Recompile o aplicativo.
Fase 4: Re-teste, Revisão Quantitativa e Porta de Decisão
Execute novamente o perfil sob condições idênticas e avalie o delta:
# 1. Grave a carga de trabalho ativa pós-otimização
"$SKILL_DIR/scripts/run_trace.sh" --process "$APP_NAME" --template power --duration 60s --label "03-post-opt"
# 2. Compare Pré-Otimização vs Pós-Otimização em relação à Linha de Base
python3 "$SKILL_DIR/scripts/compare_elements.py" \
/tmp/macos-traces/01-baseline-power.xml:"Linha de Base Ociosa" \
/tmp/macos-traces/02-pre-opt-power.xml:"Ativo Pré-Otimização" \
/tmp/macos-traces/03-post-opt-power.xml:"Ativo Pós-Otimização"
Exemplo de Saída de Decisão:
Cenário Seg Média CPU Máx CPU Exibição Média GPU Instr Totais Instr M/s
====================================================================================================
Linha de Base Ociosa 60 0,15 0,80 0,05 0,00 1,02G 17,0
Ativo Pré-Otimização 60 2,40 4,80 1,10 1,50 16,20G 270,0
Ativo Pós-Otimização 60 0,65 1,20 0,25 0,10 4,80G 80,0
----------------------------------------------------------------------------------------------------
Diferencial vs Linha de Base [Linha de Base Ociosa]:
Ativo Pré-Otimização +253,0 M/s instruções, Delta Médio CPU +2,25
Ativo Pós-Otimização +63,0 M/s instruções, Delta Médio CPU +0,50
Porta de Decisão:
- Se a meta foi atingida (por exemplo, a taxa de instruções caiu de 270 M/s para 80 M/s, satisfazendo a meta de < 100 M/s): Apresente o relatório empírico de antes/depois ao usuário e conclua.
- Se a meta não foi atingida: Isole o gargalo restante e inicie o próximo ciclo de iteração.
Limpeza Pós-Relatório: Após o usuário aceitar o relatório de otimização final, exclua os bundles .trace acumulados em /tmp/macos-traces/ (cada um pode ter dezenas de GB), a menos que o usuário peça explicitamente para mantê-los. A tabela de comparação finalizada e as exportações .xml mostradas no relatório são evidências suficientes.
Referência Direta da CLI
# Anexar a um processo em execução
xcrun xctrace record \
--template 'Power Profiler' \
--time-limit 60s \
--output /tmp/macos-traces/power.trace \
--attach $PID
# Exportar tabela de Impacto de Energia (instruções, CPU, GPU, exibição)
xcrun xctrace export \
--input /tmp/macos-traces/power.trace \
--xpath "/trace-toc/run[@number='1']/data/table[@schema='ProcessSubsystemPowerImpact']" \
> /tmp/macos-traces/power.xml
# Exportar tabela de resumo de Alocações
xcrun xctrace export \
--input /tmp/macos-traces/alloc.trace \
--xpath "/trace-toc/run[@number='1']/data/table[@schema='all-allocations-summary']" \
> /tmp/macos-traces/alloc.xml
Referência de Modelos
Modelos do Instruments suportados por scripts/run_trace.sh e xctrace headless:
Computação e Energia
| Modelo | Nome Curto | Métricas Alvo e Esquema de Exportação | Caso de Uso |
|---|---|---|---|
Power Profiler | power | Instruções/s (M/s), impactos de energia CPU/GPU/Exibição (ProcessSubsystemPowerImpact). | Benchmarking A/B objetivo e teste de eficiência energética. |
Time Profiler | time | Pesos de amostra da CPU por thread, hotspots de árvore de chamada, métodos de bloqueio da thread principal. | Alta utilização da CPU, threads descontroladas e caminhos de função quentes. |
CPU Counters | counters | IPC (instruções por ciclo), erros de cache L1/L2, previsões incorretas de desvio. | Gargalos de desempenho computacional de baixo nível e algoritmos DSP. |
Responsividade e Suavidade da UI
| Modelo | Nome Curto | Métricas Alvo e Esquema de Exportação | Caso de Uso |
|---|---|---|---|
Animation Hitches | hitches | Duração do engasgo (ms), taxa de engasgo (ms/s), quedas de quadros, latência da fase do aplicativo vs. renderização. | Engasgos de rolagem, quedas de quadros de animação e atrasos de commit do CoreAnimation. |
SwiftUI | swiftui | Avaliações de corpo de visualização, contagens de invalidação de Estado, frequência de atualização de visualização. | Reavaliações de visualização desnecessárias e cascatas de invalidação de estado. |
Metal System Trace | metal | Tempo de codificador da GPU, durações de shader de vértice/fragmento, latência de limite de quadro. | Gargalos de execução de shader, sobrecarga de efeitos de partículas e paradas no pipeline de renderização. |
Memória e Alocações
| Modelo | Nome Curto | Métricas Alvo e Esquema de Exportação | Caso de Uso |
|---|---|---|---|
Allocations | alloc | Alocações heap, memória transitória vs. persistente, taxas de evento por categoria (all-allocations-summary). | Alocações temporárias de alta frequência, picos de memória e oscilações de buffer. |
Leaks | leaks | Vazamentos de memória retidos que sobrevivem ao ciclo de vida pai, ciclos de referência. | Memória abandonada, vazamentos de captura de closure e ciclos de delegado não liberados. |
Inicialização e Concorrência
| Modelo | Nome Curto | Métricas Alvo e Esquema de Exportação | Caso de Uso |
|---|---|---|---|
App Launch | launch | Tempo para o primeiro quadro, tempo de carregamento dyld, inicializadores estáticos, configuração do runloop. | Otimização de inicialização a frio (--launch -- <binary_path>). |
Swift Concurrency | concurrency | Swift Tasks (criadas/em execução/suspensas), reentrância de Actor, uso do pool cooperativo. | Falta de recursos async/await, contenção de Actor e tarefas longamente suspensas. |
System Trace | sys | Transições de estado de thread (Em execução... [truncado para tradução] |