Przejdź do treści

Testy wydajnościowe

Repozytorium zawiera zestaw testów wydajnościowych w lokalizacjach bin/ i benchmarks/. Mierzy on każdy tryb wyszukiwania na rzeczywistych korpusach (WordPress, Laravel) oraz wygenerowanych syntetycznych zbiorach danych, zapisuje ustrukturyzowane raporty i umożliwia porównanie dwóch serii raportów.

Zestaw testów jest częścią repozytorium, a nie pakietu Composer: ponieważ 0.2.3, benchmarks/ i skrypty bin/bench* są pomijane w pakiecie, uruchamiaj je ze sklonowanego repozytorium (git clone https://github.com/inline0/greph && cd greph && composer install).

Opublikowane wyniki w README pochodzą z uruchomień GitHub Actions, nigdy z komputerów lokalnych. Uruchomienia lokalne są przydatne podczas iteracji; źródłem prawdy są uruchomienia CI.

Korpusy danych

Syntetyczne korpusy danych (synthetic-1k, synthetic-10k, synthetic-100k-single) są generowane w benchmarks/corpora/synthetic/ przy pierwszym uruchomieniu. Rzeczywiste korpusy nie są dołączone: umieść kopię repozytorium w benchmarks/corpora/wordpress lub benchmarks/corpora/laravel (workflow CI klonuje WordPress/WordPress za pomocą --depth=1). Korpus z brakującym katalogiem jest pomijany.

Uruchamianie testów wydajnościowych

Powłoka
# 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 porównuje dwa pliki z seriami wyników (wyjście polecenia bench-series lub bench-aggregate) i wyświetla podsumowanie Markdown przydatne podczas optymalizacji krytycznej ścieżki. bin/bench-ci uruchamia workflow Benchmark w GitHub Actions za pośrednictwem gh CLI.

Kategorie

README publikuje osiem grup wyników, z których każda mierzy konkretną warstwę silnika. Każda grupa obejmuje jedną lub więcej kategorii zestawu testów zdefiniowanych w benchmarks/suites/.

Tryb skanowania: tekst

Natywne wyszukiwanie tekstu z użyciem wzorców dosłownych, wyrażeń regularnych i ich połączeń. Opublikowany wynik bazowy pochodzi z korpusu WordPress i obejmuje:

  • Dosłowny function
  • Dosłowny bez uwzględniania wielkości liter
  • Dosłowny z dopasowaniem całych słów
  • Nowa instancja wyrażenia regularnego
  • Wywołanie tablicy wyrażeń regularnych
  • Dosłowny prefiks wyrażenia regularnego
  • Dosłowny sufiks wyrażenia regularnego
  • Dosłowny pełny wiersz wyrażenia regularnego
  • Upraszczanie dosłownych wyrażeń regularnych

Tryb skanowania: przechodzenie po plikach

Samo przechodzenie po plikach, bez wyszukiwania. Mierzy koszt działania mechanizmu uwzględniającego gitignore.

Tryb skanowania: tekst równoległy

Wyszukiwanie dokładnego ciągu function z użyciem 1, 2 i 4 zadań. Dla tego wzorca pula procesów roboczych uruchamia się dopiero powyżej jobs * 4_000 plików (zob. Równoległe procesy robocze), czyli liczby większej niż zawartość korpusu WordPress. Dlatego wszystkie trzy opublikowane wiersze działają w jednym procesie i nie pokazują skalowania puli (#8).

Tryb skanowania: AST

Natywne wyszukiwanie AST z użyciem reprezentatywnych wzorców:

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

Indeksowany tryb tekstowy

Rozgrzane indeksowane wyszukiwanie tekstu z użyciem tych samych wzorców co w trybie skanowania. Obejmuje zapytania dotyczące dopasowań dosłownych, bez uwzględniania wielkości liter, całych słów, krótkich tokenów i wyrażeń regularnych.

Indeksowane zapytania podsumowujące

Rozgrzane indeksowane wyszukiwanie tekstu zwracające liczbę wyników, pliki z dopasowaniami i pliki bez dopasowań. Te zapytania najbardziej korzystają z magazynu wystąpień, ponieważ operacje na poszczególnych plikach są najtańsze.

Indeksowane / buforowane AST

Rozgrzane wyszukiwanie faktów AST i wyszukiwanie AST z pamięci podręcznej przy użyciu tych samych wzorców co w trybie skanowania AST.

Koszty kompilacji

Koszty zimnej kompilacji indeksu trigramowego, indeksu faktów AST i pamięci podręcznej AST. Przydatne przy wyborze trybu, który warto utrzymywać dla danego obciążenia.

Jak odczytywać opublikowane wyniki

README publikuje migawkę najnowszego uruchomienia CI dla każdej wartości bazowej. Każda sekcja pochodzi z konkretnego uruchomienia GitHub Actions i zawiera oznaczenia korpusu, maszyny wykonawczej, wersji PHP oraz liczby mierzonych uruchomień i rozgrzewek. Aby odtworzyć wynik, użyj lokalnie tej samej konfiguracji.

Kolumny porównania (rg, grep, sg) są zbierane w ramach tego samego zadania, na tej samej maszynie wykonawczej i dla tego samego korpusu. Nie są ekstrapolowane z zewnętrznych testów wydajnościowych.

Jak dodać test wydajnościowy

  1. Dodaj definicję testu wydajnościowego w benchmarks/.
  2. Dodaj odpowiedni scenariusz do zestawu regresji, jeśli jeszcze go tam nie ma, aby zweryfikować również mierzone zachowanie.
  3. Uruchom ./bin/bench --category <yours>, aby sprawdzić nowy test wydajnościowy.
  4. Porównaj wyniki z main za pomocą workflow Benchmark, które uruchamia się dla żądań pull request dotyczących src/, benchmarks/ lub bin/ i publikuje porównanie bieżącej wersji z bazową w podsumowaniu uruchomienia.
  5. Zaktualizuj tabelę README, gdy uruchomienie CI obejmujące nowy test zostanie scalone z main.

Założenia dotyczące wydajności

Greph nie próbuje wyprzedzić ripgrep ani grep podczas zimnych skanów. Ripgrep jest zaimplementowany w Rust z ręcznie dostrojonym skanowaniem dosłownych ciągów za pomocą SIMD; w opublikowanych wynikach zarówno rg, jak i GNU grep są szybsze niż Greph podczas każdego zimnego skanowania tekstu. Cele są inne:

  • Działać na tyle szybko, aby interakcja z narzędziem i praca agentów przebiegały naturalnie.
  • Obsługiwać powtarzane zapytania za pomocą rozgrzanych indeksów: indeksowane zapytania dotyczące wyrażeń regularnych, liczby wyników i list plików są szybsze niż skanowanie tego samego drzewa przez rg i grep.
  • Wyprzedzać ast-grep w indeksowanych i buforowanych obciążeniach AST, w których rozgrzane pamięci podręczne Greph pozwalają uniknąć ponownej analizy drzewa. Wyniki zimnego wyszukiwania AST są mieszane: new $CLASS() jest szybsze niż sg, a array($$$ITEMS) jest wolniejsze.
  • Sprawiać, by każdy wzrost wydajności dało się zmierzyć i odtworzyć.

Twierdzenia dotyczące wydajności, które nie są poparte raportem z testów, nie są wdrażane.