Перейти до вмісту

Тестування продуктивності

У репозиторії є набір інструментів для тестування продуктивності в bin/ та benchmarks/. Він вимірює кожен режим пошуку на реальних корпусах даних (WordPress, Laravel) і згенерованих синтетичних наборах даних, зберігає структуровані звіти та дає змогу порівнювати два ряди звітів.

Набір інструментів є частиною репозиторію, а не пакета Composer: оскільки 0.2.3, benchmarks/ та скрипти bin/bench* не входять до пакета, запускайте їх із клону (git clone https://github.com/inline0/greph && cd greph && composer install).

Опубліковані результати в README отримані під час запусків GitHub Actions, а не на локальних машинах. Локальні запуски корисні для ітерацій, а джерело істини — запуски CI.

Корпуси даних

Синтетичні корпуси даних (synthetic-1k, synthetic-10k, synthetic-100k-single) генеруються в benchmarks/corpora/synthetic/ під час першого запуску. Реальні корпуси не включено: розмістіть копію репозиторію в benchmarks/corpora/wordpress або benchmarks/corpora/laravel (процес CI клонує WordPress/WordPress за допомогою --depth=1). Корпус із відсутнім каталогом пропускається.

Запуск тестування продуктивності

Командна оболонка
# Full benchmark suite, every corpus that is present
./bin/bench

# Specific category (the category names used in benchmarks/suites/)
./bin/bench --category text
./bin/bench --category ast

# Compare against external tools when available
./bin/bench --compare rg,grep
./bin/bench --compare sg

# Choose a corpus
./bin/bench --corpus wordpress
./bin/bench --corpus laravel
./bin/bench --corpus synthetic-1k

# Write the run as JSON
./bin/bench --corpus wordpress --output build/run-1.json

# Measured series: 5 runs after 1 warmup run
./bin/bench-series --repeat 5 --warmup 1 --corpus wordpress --output build/head-series.json

# Aggregate separate runs into one series
./bin/bench-aggregate --output build/head-series.json build/run-*.json

bin/bench-compare base-series.json head-series.json порівнює два файли рядів (результати bench-series або bench-aggregate) і виводить зведення Markdown, корисне під час роботи над критично важливою ділянкою коду. bin/bench-ci запускає процес Benchmark на GitHub Actions через gh CLI.

Категорії

README публікує вісім груп результатів, кожна з яких вимірює окремий рівень рушія. Кожна група охоплює одну або кілька категорій набору інструментів, визначених у benchmarks/suites/.

Режим сканування: текст

Власний текстовий пошук за літеральними, регулярними та комбінованими шаблонами. Опублікований базовий результат отримано на корпусі WordPress; він охоплює:

  • Літеральний function
  • Літеральний без урахування регістру
  • Літеральний пошук цілих слів
  • Регулярний вираз, новий екземпляр
  • Масивний виклик регулярного виразу
  • Літеральний префікс у регулярному виразі
  • Літеральний суфікс у регулярному виразі
  • Літеральний пошук точного рядка в регулярному виразі
  • Згортання літералів у регулярному виразі

Режим сканування: обхід

Лише обхід файлів, без пошуку. Вимірює окремо витрати на обхід із підтримкою gitignore.

Режим сканування: паралельний текст

Пошук за фіксованим рядком function із завданнями 1, 2 та 4. Для цього шаблону пул воркерів запускається лише за наявності понад jobs * 4_000 файлів (див. Паралельні воркери), а в корпусі WordPress файлів менше, тому всі три опубліковані рядки виконуються в одному процесі й не демонструють масштабування пулу (#8).

Режим сканування: AST

Власний пошук AST за типовими шаблонами:

  • new $CLASS()
  • array($$$ITEMS)

Режим індексованого тексту

Пошук в індексованому тексті з прогрітим індексом за тими самими шаблонами, що й у режимі сканування. Містить запити для літералів, без урахування регістру, цілих слів, коротких токенів і регулярних виразів.

Запити до індексованого зведення

Пошук в індексованому тексті з прогрітим індексом із виведенням кількості, файлів із збігами та файлів без збігів. Ці запити найбільше виграють від сховища інвертованого індексу, оскільки обробка кожного файла потребує найменше ресурсів.

Індексований / кешований AST

Пошук фактів AST з прогрітим індексом і кешований пошук AST за тими самими шаблонами, що й у режимі сканування AST.

Витрати на збирання

Витрати на холодне збирання триграмного індексу, індексу фактів AST і кешу AST. Допомагає вирішити, який режим підтримувати для певного робочого навантаження.

Як читати опубліковані результати

README публікує знімок останнього запуску CI для кожного базового тесту. Дані в кожному розділі отримано під час конкретного запуску GitHub Actions; зазначено корпус даних, виконавче середовище, версію PHP, а також кількість вимірювань і прогрівань. Щоб відтворити результат, використовуйте ту саму комбінацію локально.

Значення в стовпцях порівняння (rg, grep, sg) зібрано в тому самому завданні, на тому самому виконавчому середовищі та на тому самому корпусі даних. Їх не екстрапольовано із зовнішніх тестів продуктивності.

Як додати тест продуктивності

  1. Додайте визначення тесту продуктивності в benchmarks/.
  2. Додайте відповідний сценарій до набору регресійних тестів, якщо рівноцінного ще немає (щоб перевірити й поведінку, яку вимірює тест).
  3. Запустіть ./bin/bench --category <yours>, щоб перевірити новий тест продуктивності.
  4. Порівняйте з main за допомогою процесу Benchmark, який запускається для запитів на злиття зі змінами в src/, benchmarks/ або bin/ та публікує порівняння поточної і базової версій у зведенні запуску.
  5. Оновіть таблицю README після додавання нового тесту продуктивності до main під час запуску CI.

Принципи продуктивності

Greph не намагається випередити ripgrep чи grep під час холодного сканування. Ripgrep реалізовано на Rust з оптимізованим вручну SIMD-скануванням літералів, і в опублікованих результатах і rg, і GNU grep швидші за Greph у кожному холодному текстовому скануванні. Цілі в них різні:

  • Працювати достатньо швидко, щоб інтерактивне використання та цикли агентів відчувалися природно.
  • Відповідати на повторні запити за прогрітими індексами: індексований пошук регулярних виразів, підрахунок і запити списку файлів швидші, ніж rg і grep, що сканують те саме дерево.
  • Перевершувати ast-grep на індексованих і кешованих навантаженнях AST, де прогріті кеші Greph дають змогу не розбирати дерево повторно. Пошук AST без прогрівання кешу показує різні результати: new $CLASS() швидший за sg, а array($$$ITEMS) повільніший.
  • Робити кожне покращення продуктивності вимірюваним і відтворюваним.

Заяви про продуктивність, не підтверджені звітом бенчмарку, не приймаються.