ベンチマーク
リポジトリにはbin/とbenchmarks/の下にベンチマークハーネスがあります。実データのコーパス(WordPress、Laravel)と生成した合成データセットを使って各検索モードを測定し、構造化レポートを収集して、2つのレポート系列を比較できます。
ハーネスはリポジトリの一部であり、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ワークフローは--depth=1を使ってWordPress/WordPressをクローンします)。ディレクトリが見つからないコーパスはスキップされます。
ベンチマークの実行
# 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は2つの系列ファイル(bench-seriesまたはbench-aggregateの出力)を比較し、Markdownの概要を表示します。処理が集中する箇所の改善を繰り返す際に便利です。bin/bench-ciは、gh CLIを通じてGitHub Actionsのベンチマークワークフローを起動します。
カテゴリー
READMEでは、エンジンの特定の層を測定する8つの結果グループを公開しています。各グループには、benchmarks/suites/で定義された1つ以上のハーネスカテゴリーが含まれます。
スキャンモード: テキスト
リテラル、正規表現、組み合わせパターンを使ったネイティブのテキスト検索です。公開されているベースラインはWordPressコーパスで実行され、以下を含みます:
- リテラル
function - 大文字小文字を区別しないリテラル
- 単語全体のリテラル
- 新しいインスタンスでの正規表現
- 配列呼び出しでの正規表現
- 接頭辞リテラルの正規表現
- 接尾辞リテラルの正規表現
- 行全体と一致するリテラルの正規表現
- リテラルをまとめた正規表現
スキャンモード: トラバーサル
検索を行わず、ファイルの走査のみを実行します。gitignore対応のウォーカー単体のコストを測定します。
スキャンモード: 並列テキスト
functionを1、2、4ジョブで検索する固定文字列検索です。このパターンでは、ワーカープールが起動するのはjobs * 4_000ファイルを超える場合だけです(並列ワーカーを参照)。WordPressコーパスはその数に満たないため、公開されている3つの行はすべて単一プロセスで実行され、プールの拡張性を示していません(#8)。
スキャンモード: AST
代表的なパターンを使ったネイティブAST検索:
new $CLASS()array($$$ITEMS)
インデックス付きテキストモード
スキャンモードと同じパターンを使った、ウォーム状態のインデックス付きテキスト検索です。リテラル、大文字小文字を区別しない検索、単語全体の検索、短いトークン、正規表現クエリを含みます。
インデックス付き概要クエリ
件数、一致するファイル、一致しないファイルを出力する、ウォーム状態のインデックス付きテキスト検索です。ファイルごとの処理が最も少ないため、転置インデックスの恩恵を特に受けます。
インデックス付き/キャッシュ済みAST
ASTスキャンモードと同じパターンを使った、ウォーム状態でのAST事実検索とキャッシュ済みAST検索です。
ビルドコスト
トライグラムインデックス、AST事実インデックス、ASTキャッシュのコールドビルド時のコストです。ワークロードに応じて維持するモードを決める際に役立ちます。
公開されている測定値の読み方
READMEでは、各ベースラインについて最新のCI実行結果を掲載しています。各セクションには、測定元のGitHub Actionsの実行と、コーパス、ランナー、PHPのバージョン、測定回数、ウォームアップ回数が記載されています。数値を再現する場合は、ローカルで同じ組み合わせを使用してください。
比較列(rg、grep、sg)は、同じジョブ内で、同じランナーとコーパスを使って収集しています。外部のベンチマークから推定した値ではありません。
ベンチマークの追加方法
benchmarks/の下にベンチマーク定義を追加します。- 同等のシナリオがまだない場合は、回帰テストスイートに対応するシナリオを追加します(測定対象の動作も検証できるようにします)。
./bin/bench --category <yours>を実行して、新しいベンチマークを検証します。- ベンチマークワークフローで
mainと比較します。このワークフローは、src/、benchmarks/、bin/に関係するプルリクエストで実行され、実行概要に変更前後の比較を投稿します。 - 新しいベンチマークを含むCI実行が
mainに反映されたら、READMEの表を更新します。
パフォーマンスに関する方針
Grephは、低温時のスキャンでripgrepやgrepを上回ることを目指していません。RipgrepはRustで実装され、手作業で調整したSIMDリテラルスキャンを使います。公開されている数値では、rgとGNUgrepは、すべての低温テキストスキャンでGrephより高速です。目指すものはそれぞれ異なります。
- 対話的な利用やエージェントの処理ループで、ネイティブに感じられるほど高速にする。
- ウォーム状態のインデックスから繰り返しのクエリに応答する。インデックス付きの正規表現、件数、ファイル一覧のクエリは、同じツリーをスキャンする
rgとgrepの両方より高速です。 - インデックス付きおよびキャッシュ済みASTのワークロードで
ast-grepを上回る。Grephはウォームキャッシュによりツリーの再解析を避けられます。コールドAST検索の結果は一様ではなく、new $CLASS()はsgより高速ですが、array($$$ITEMS)は低速です。 - パフォーマンス改善をすべて測定可能かつ再現可能にする。
ベンチマークレポートで裏付けられていないパフォーマンスの主張は採用されません。