본문으로 건너뛰기

벤치마크

저장소에는 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 워크플로는 --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은 두 시리즈 파일(bench-series 또는 bench-aggregate의 출력)을 비교해 Markdown 요약을 출력하므로 핫 패스를 반복 개선할 때 유용합니다. bin/bench-ci는 gh CLI을 통해 GitHub Actions에서 Benchmark 워크플로를 실행합니다.

범주

README는 엔진의 특정 계층을 각각 측정하는 8개 결과 그룹을 게시합니다. 각 그룹은 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. 새 벤치마크가 포함된 CI 실행이 main에 반영되면 README 표를 업데이트합니다.

성능 철학

Greph는 콜드 스캔에서 ripgrep 또는 grep보다 앞서려 하지 않습니다. Ripgrep는 수작업으로 튜닝한 SIMD 리터럴 스캔을 사용해 Rust에서 구현되며, 게시된 수치에서 rg와 GNU grep 모두 모든 콜드 텍스트 스캔에서 Greph보다 빠릅니다. 목표는 다릅니다:

  • 대화형 사용과 에이전트 루프에서 기본 도구처럼 느껴질 만큼 빠르게 동작합니다.
  • 워밍된 인덱스에서 반복 쿼리에 응답합니다. 인덱스 정규식, 인덱스 개수 및 파일 목록 쿼리는 동일한 트리를 스캔하는 rg 및 grep보다 빠릅니다.
  • 인덱스 및 캐시된 AST 워크로드에서 ast-grep보다 빠르게 동작합니다. Greph의 워밍된 캐시는 트리를 다시 구문 분석하지 않습니다. 콜드 AST 검색 결과는 엇갈립니다. new $CLASS()는 sg보다 빠르고, array($$$ITEMS)은 더 느립니다.
  • 모든 성능 개선을 측정하고 재현할 수 있게 합니다.

벤치마크 보고서로 뒷받침되지 않는 성능 주장은 반영되지 않습니다.