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
# 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
- Dodaj definicję testu wydajnościowego w
benchmarks/. - Dodaj odpowiedni scenariusz do zestawu regresji, jeśli jeszcze go tam nie ma, aby zweryfikować również mierzone zachowanie.
- Uruchom
./bin/bench --category <yours>, aby sprawdzić nowy test wydajnościowy. - Porównaj wyniki z
mainza pomocą workflow Benchmark, które uruchamia się dla żądań pull request dotyczącychsrc/,benchmarks/lubbin/i publikuje porównanie bieżącej wersji z bazową w podsumowaniu uruchomienia. - 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
rgigrep. - Wyprzedzać
ast-grepw 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, aarray($$$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.