Skip to content

Perfil de desempenho

Compilar o oxlint em release com informações de debug

Para profiling, compile o binário oxlint em modo release com símbolos de debug. Passe --profile release-with-debug ao cargo build:

bash
cargo build --profile release-with-debug --bin oxlint

Depois da build, o binário fica em ./target/release-with-debug/oxlint. É esse binário que você deve usar no profiling.

CPU — Samply

Samply é um profiler de CPU em linha de comando que usa a UI do Firefox Profiler. Funciona em macOS e Linux.

Para usar o Samply com oxlint, rode samply record seguido do comando e argumentos do oxlint:

bash
samply record ./target/release-with-debug/oxlint .

Para melhorar a experiência de profiling, considere:

  • oxlint: --silent suprime a saída de diagnósticos e deixa o perfil mais limpo.
  • oxlint: --threads 1 roda o linter numa única thread (mais lento, mas facilita analisar desempenho “single-thread”).
  • samply record: --rate <number> aumenta a taxa de amostragem. O padrão é 1000 Hz (1 ms); valores maiores dão mais detalhe ao custo de um arquivo de perfil maior.

Exemplo com uma thread e taxa de 0,1 ms:

bash
samply record --rate 10000 ./target/release-with-debug/oxlint --silent --threads 1 .

CPU — Xcode Instruments no Mac

cargo instruments é a ferramenta usual para ligar o Instruments do Xcode no Mac.

O que segue reproduz o fluxo do cargo instruments.

Primeiro, instale as ferramentas de linha de comando do Xcode Instruments:

bash
xcode-select --install

Depois, se ainda não fez, garanta que o binário oxlint foi compilado.

Por baixo dos panos, cargo instruments chama xcrun xctrace, equivalente a:

bash
xcrun xctrace record --template 'Time Profile' --output . --launch -- /path/to/oxc/target/release-with-debug/oxlint

Rodando o comando acima, a saída tende a ser assim:

Starting recording with the Time Profiler template. Launching process: oxlint.
Ctrl-C to stop the recording
Target app exited, ending recording...
Recording completed. Saving output file...
Output file saved as: Launch_oxlint_2023-09-03_4.41.45 PM_EB179B85.trace

Abra o arquivo de trace com open Launch_oxlint_2023-09-03_4.41.45\ PM_EB179B85.trace.

Para uma visão top-down:

  1. No painel superior, clique em CPUs
  2. Na caixa à esquerda, clique em x e escolha Time Profiler
  3. No painel inferior, clique em "Call Tree", ative "Invert Call Tree" e desative separate by thread.

Para memória e disco, use --template 'Allocations' e --template 'File Activity'.

Para profiling de CPU mais fino (faltas L1/L2, ciclos e instruções, branches etc.), use um template customizado "CPU Counters":

  1. Abra o Instruments e selecione o template "CPU Counters".
  2. Nas configurações de "CPU Counters":
    1. Ative "High Frequency Sampling".
    2. Abaixo dessa opção, clique no "+" e escolha um tipo de evento. Sugestões:
      • Cycles — ideia grosseira de ciclos por função
      • Instructions — instruções por função e quantos ciclos isso leva
      • L1D_CACHE_MISS_LD — faltas de cache L1 ao carregar da memória
  3. Com os eventos que interessam ativos, salve o template em "File > Save as Template ..." com um nome.
  4. Use esse nome em --template no xctrace: xcrun xctrace record --template 'My Custom CPU Counters' --output . --launch -- /path/to/oxc/target/release-with-debug/oxlint

Heap — dhat

dhat é um profiler de heap que ajuda a achar vazamentos e entender padrões de alocação.

Configuração

Adicione o dhat como dependência no Cargo.toml:

toml
[dependencies]
dhat = "0.3"

Depois adicione um alocador global no topo do crate do binário:

rust
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;

Profiling

Crie um profiler no escopo que quiser medir. Ele conta alocações desde a criação até o drop:

rust
fn main() {
    let _profiler = dhat::Profiler::new_heap();
    // Your code here - all heap allocations will be tracked
}

Você também pode colocar _profiler em qualquer função para medir só aquele escopo:

rust
fn my_function() {
    let _profiler = dhat::Profiler::new_heap();
    // Only allocations within this function scope will be tracked
}

Ao dropar o profiler, um arquivo dhat-heap.json é gerado automaticamente.

Abrir e ler o perfil

Depois de rodar o programa, dhat-heap.json aparece no diretório de trabalho.

Para analisar:

  1. Abra o visualizador em https://nnethercote.github.io/dh_view/dh_view.html
  2. Carregue o arquivo dhat-heap.json
  3. Em "Sort metrics", escolha a métrica:
    • "At t-gmax (bytes)": alocações no pico de uso de memória — útil para ver o que mais pesa no heap máximo.
    • "At t-end (bytes)": memória que não foi liberada antes do fim do profiler — bom para vazamentos e alocações que sobram ao final.
    • "Total (bytes)": total alocado na execução — mostra onde mais se aloca, mesmo que depois libere.

Avançado: controlar o tempo de vida do profiler

Para parar o profiling de forma explícita, gerencie o lifetime do profiler. Por exemplo, para medir só a lógica central e excluir cleanup:

rust
struct MyApp {
    profiler: Option<dhat::Profiler>,
    // other fields
}

impl MyApp {
    fn close(&mut self) {
        // Drop the profiler here to capture the heap state before cleanup
        self.profiler = None;
        // cleanup code
    }
}

Esse padrão ajuda a ver quais estruturas seguram memória em um ponto específico da execução.