コンテンツへスキップ

ベンチマーク

リポジトリには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)は、同じジョブ内で、同じランナーとコーパスを使って収集しています。外部のベンチマークから推定した値ではありません。

ベンチマークの追加方法

  1. benchmarks/の下にベンチマーク定義を追加します。
  2. 同等のシナリオがまだない場合は、回帰テストスイートに対応するシナリオを追加します(測定対象の動作も検証できるようにします)。
  3. ./bin/bench --category <yours>を実行して、新しいベンチマークを検証します。
  4. ベンチマークワークフローでmainと比較します。このワークフローは、src/、benchmarks/、bin/に関係するプルリクエストで実行され、実行概要に変更前後の比較を投稿します。
  5. 新しいベンチマークを含むCI実行がmainに反映されたら、READMEの表を更新します。

パフォーマンスに関する方針

Grephは、低温時のスキャンでripgrepやgrepを上回ることを目指していません。RipgrepはRustで実装され、手作業で調整したSIMDリテラルスキャンを使います。公開されている数値では、rgとGNUgrepは、すべての低温テキストスキャンでGrephより高速です。目指すものはそれぞれ異なります。

  • 対話的な利用やエージェントの処理ループで、ネイティブに感じられるほど高速にする。
  • ウォーム状態のインデックスから繰り返しのクエリに応答する。インデックス付きの正規表現、件数、ファイル一覧のクエリは、同じツリーをスキャンするrgとgrepの両方より高速です。
  • インデックス付きおよびキャッシュ済みASTのワークロードでast-grepを上回る。Grephはウォームキャッシュによりツリーの再解析を避けられます。コールドAST検索の結果は一様ではなく、new $CLASS()はsgより高速ですが、array($$$ITEMS)は低速です。
  • パフォーマンス改善をすべて測定可能かつ再現可能にする。

ベンチマークレポートで裏付けられていないパフォーマンスの主張は採用されません。