Skip to content

Профилирование

Сборка oxlint в release с отладочной символикой

Для профилирования соберите бинарник oxlint в режиме release с отладочной информацией:

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

Бинарник: ./target/release-with-debug/oxlint — его и нужно использовать при профилировании.

CPU — Samply

Samply — профилировщик CPU из командной строки с UI Firefox Profiler. Работает на macOS и Linux.

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

Полезные опции:

  • oxlint: --silent убирает диагностики из вывода.
  • oxlint: --threads 1 — один поток, проще анализировать однопоточную часть.
  • samply record --rate <число> — выше частота выборки (по умолчанию 1000 Гц); файл профиля станет больше.

Пример однопоточного запуска с шагом 0.1 мс:

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

CPU — Xcode Instruments (Mac)

cargo instruments — обёртка над Xcode Instruments.

Установите инструменты командной строки:

bash
xcode-select --install

Убедитесь, что бинарник собран (см. выше).

Под капотом вызывается примерно:

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

Пример вывода:

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

Откройте trace: open Launch_oxlint_2023-09-03_4.41.45\ PM_EB179B85.trace.

Сверху вниз:

  1. Панель сверху → CPUs
  2. Слева сбросьте фильтр (x) → Time Profiler
  3. Внизу «Call Tree»: включите «Invert Call Tree», отключите разбиение по потокам.

Для памяти и диска: --template 'Allocations' и --template 'File Activity'.

Точнее по CPU (кэш L1/L2, циклы, инструкции, ветвления) — шаблон «CPU Counters»:

  1. Откройте Instruments → шаблон CPU Counters.
  2. В настройках включите High Frequency Sampling и добавьте счётчики (Cycles, Instructions, L1D_CACHE_MISS_LD и т.д.).
  3. Сохраните шаблон через File → Save as Template.
  4. Используйте имя в --template, например: xcrun xctrace record --template 'My Custom CPU Counters' --output . --launch -- /path/to/oxc/target/release-with-debug/oxlint

Куча — dhat

dhat помогает искать утечки и смотреть паттерны аллокаций на куче.

Подключение

В Cargo.toml:

toml
[dependencies]
dhat = "0.3"

В начале бинарного crate:

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

Запись профиля

Профайлер считает аллокации от создания до уничтожения:

rust
fn main() {
    let _profiler = dhat::Profiler::new_heap();
    // код под наблюдением
}

Или только внутри функции:

rust
fn my_function() {
    let _profiler = dhat::Profiler::new_heap();
}

При drop создаётся dhat-heap.json.

Просмотр

  1. Откройте https://nnethercote.github.io/dh_view/dh_view.html
  2. Загрузите dhat-heap.json
  3. Метрики в «Sort metrics»:
    • At t-gmax (bytes) — что занимало память в пике
    • At t-end (bytes) — что не освобождено к концу (утечки)
    • Total (bytes) — суммарный объём аллокаций за сеанс

Явное управление временем жизни

Чтобы обрезать хвост очистки и смотреть состояние кучи раньше:

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

impl MyApp {
    fn close(&mut self) {
        self.profiler = None;
        // очистка
    }
}

Так проще понять, какие структуры держат память в заданной точке выполнения.