- Add schema.json with complete baseline metrics definition - Required fields: commit_sha, timestamp, pdftract_geomean, grep_1000_mean_ms - Optional fields: throughput_mb_per_sec, files_per_sec, total_runtime_sec - All fields include types, units, descriptions, and examples - Follows JSON Schema draft-07 specification - Add README.md with comprehensive documentation - Purpose and use cases for baseline metrics - Complete field reference with types and units - Schema validation instructions - CI/CD integration guidelines - Performance targets from project plan - Update procedures and regression detection - Validate existing main.json against schema structure - All required fields present and correctly formatted Acceptance criteria: ✓ benches/baselines/ directory exists ✓ JSON schema documented with all required fields ✓ README explains baseline format and purpose ✓ Schema includes types and units for each metric
145 lines
5.4 KiB
Markdown
145 lines
5.4 KiB
Markdown
# Baseline Metrics
|
||
|
||
This directory stores baseline benchmark metrics for pdftract performance validation and regression tracking.
|
||
|
||
## Purpose
|
||
|
||
Baseline metrics serve as the reference point for:
|
||
- **Performance regression detection** - Compare current benchmark results against historical baselines
|
||
- **Competitive analysis** - Track pdftract performance relative to pdfminer.six, pypdf, and pdfplumber
|
||
- **CI/CD gates** - Block releases that introduce performance regressions beyond acceptable thresholds
|
||
- **Trend analysis** - Monitor performance improvements over time
|
||
|
||
## File Format
|
||
|
||
Each baseline file is a JSON document conforming to `schema.json`. The schema defines the following structure:
|
||
|
||
### Required Fields
|
||
|
||
| Field | Type | Unit | Description |
|
||
|-------|------|------|-------------|
|
||
| `commit_sha` | string | - | Git commit SHA (or "main" for tracking branch) |
|
||
| `timestamp` | string | ISO 8601 | When the baseline was recorded |
|
||
| `pdftract_geomean` | number | seconds | Geometric mean extraction time across all fixtures (pdftract) |
|
||
| `grep_1000_mean_ms` | number | milliseconds | Mean time for 1000-PDF corpus search |
|
||
|
||
### Optional Fields
|
||
|
||
| Field | Type | Unit | Description |
|
||
|-------|------|------|-------------|
|
||
| `pdfminer_geomean` | number | seconds | Geometric mean extraction time (pdfminer.six) |
|
||
| `pypdf_geomean` | number | seconds | Geometric mean extraction time (pypdf) |
|
||
| `pdfplumber_geomean` | number | seconds | Geometric mean extraction time (pdfplumber) |
|
||
| `throughput_mb_per_sec` | number | MB/s | Aggregate throughput for grep-corpus benchmark |
|
||
| `files_per_sec` | number | files/second | Processing rate for grep-corpus benchmark |
|
||
| `total_runtime_sec` | number | seconds | Wall-clock time for complete benchmark suite |
|
||
| `corpus_size` | integer | count | Number of PDF files in test corpus |
|
||
| `notes` | string | - | Free-form contextual information |
|
||
|
||
## Naming Convention
|
||
|
||
Baseline files are named by their Git branch or tag:
|
||
|
||
- `main.json` - Baseline for the main development branch
|
||
- `v0.1.0.json` - Baseline for release tag v0.1.0
|
||
- `v0.2.0.json` - Baseline for release tag v0.2.0
|
||
|
||
## Schema Validation
|
||
|
||
All baseline files should validate against `schema.json`:
|
||
|
||
```bash
|
||
# Validate a baseline file (requires ajv-cli or similar)
|
||
npx ajv validate --strict=false -s schema.json -d main.json
|
||
|
||
# Or use Python jsonschema
|
||
python - <<'PYTHON'
|
||
import jsonschema, json
|
||
with open('schema.json') as s, with open('main.json') as d:
|
||
jsonschema.validate(json.load(d), json.load(s))
|
||
PYTHON
|
||
```
|
||
|
||
## Usage in CI
|
||
|
||
The baseline metrics are used in CI to detect performance regressions:
|
||
|
||
1. **Baseline comparison**: Each benchmark run compares results against the appropriate baseline file
|
||
2. **Threshold checks**: Regressions exceeding 10% for primary metrics block the PR
|
||
3. **Competitive ratios**: pdftract must maintain ≥ 10× speedup vs pdfminer.six and ≥ 5× vs pypdf
|
||
|
||
## Performance Targets
|
||
|
||
Based on the Primary Objectives in the project plan:
|
||
|
||
| Metric | Target | Measurement |
|
||
|--------|--------|-------------|
|
||
| 100-page vector PDF, 4-core | < 3 seconds | `cargo bench`, `tests/fixtures/perf/` |
|
||
| 10-page scanned PDF (OCR) | < 30 seconds | includes Tesseract |
|
||
| Single-page extraction latency | < 150 ms p99 | wrk benchmark |
|
||
| Throughput vs pdfminer.six | ≥ 10× faster | Identical hardware |
|
||
| Throughput vs pypdf | ≥ 5× faster | Same benchmark suite |
|
||
| `pdftract grep` throughput | ≥ 50 MB/s | 1000-PDF corpus, 4-core |
|
||
|
||
## Updating Baselines
|
||
|
||
When to update a baseline:
|
||
|
||
1. **After a major release** - Create a new baseline file tagged with the release version
|
||
2. **After accepted performance improvements** - Update `main.json` when improvements merge
|
||
3. **Never for regressions** - Regressions should block release, not update baselines
|
||
|
||
Update process:
|
||
|
||
```bash
|
||
# Run benchmarks to generate new baseline
|
||
cargo bench --bench grep_corpus | tee /tmp/bench-results.txt
|
||
|
||
# Extract metrics and create/update baseline file
|
||
# (This step requires a helper script to parse benchmark output)
|
||
|
||
# Validate against schema
|
||
npx ajv validate --strict=false -s schema.json -d main.json
|
||
|
||
# Commit the updated baseline
|
||
git add benches/baselines/main.json
|
||
git commit -m "bench(bf-XXX): update main baseline after performance improvements"
|
||
```
|
||
|
||
## Example Baseline
|
||
|
||
```json
|
||
{
|
||
"commit_sha": "abc1234",
|
||
"timestamp": "2024-07-06T10:30:45Z",
|
||
"pdftract_geomean": 2.5,
|
||
"pdfminer_geomean": 28.0,
|
||
"pypdf_geomean": 15.0,
|
||
"pdfplumber_geomean": 32.0,
|
||
"grep_1000_mean_ms": 18.5,
|
||
"throughput_mb_per_sec": 87.3,
|
||
"files_per_sec": 920.0,
|
||
"total_runtime_sec": 1.09,
|
||
"corpus_size": 1000,
|
||
"notes": "Baseline for v0.2.0 release - OCR improvements and grep optimization"
|
||
}
|
||
```
|
||
|
||
## Regression Detection
|
||
|
||
The benchmark harness compares current results against baselines and flags regressions:
|
||
|
||
- **PASS**: All metrics within ±5% of baseline (acceptable variance)
|
||
- **WARN**: Metrics degraded 5–10% (logged, non-blocking)
|
||
- **FAIL**: Metrics degraded >10% (blocks PR merge)
|
||
- **IMPROVEMENT**: Metrics improved >5% (logged, consider baseline update)
|
||
|
||
## Historical Context
|
||
|
||
Baseline files form a historical record of pdftract's performance evolution. The `main.json` baseline represents the current state of the main branch, while tagged baselines (e.g., `v0.1.0.json`) capture performance at specific release points.
|
||
|
||
This history enables:
|
||
- Long-term performance trend analysis
|
||
- Release-to-release comparison
|
||
- Identification of performance bottlenecks
|
||
- Validation of optimization efforts
|