Background
qjson positions itself as a high-performance JSON parser, but currently lacks automated performance regression detection. Benchmarks exist (benches/lua_bench.lua) but run manually without CI enforcement.
Goal
Prevent unintentional performance degradation by adding automated benchmark comparison to CI.
Scope
In Scope
- Add Rust criterion benchmarks for core parse paths (eager/lazy, field access)
- Integrate benchmark comparison into PR CI using
benchmark-action/github-action-benchmark
- Set regression threshold: >5% degradation triggers warning (not blocking)
- Store baseline results in
gh-pages branch
Out of Scope
- Lua-level benchmarks in CI (keep manual due to OpenResty setup complexity)
- Micro-benchmarks for every function (focus on user-facing parse/access paths)
Design
1. Criterion Benchmarks
File: benches/rust_bench.rs
Benchmark groups:
parse_eager - eager mode parsing (full validation)
parse_lazy - lazy mode parsing (structural scan only)
field_access - field access operations (get_str, get_f64, nested paths)
Fixtures (based on manifest.json ci tags):
- PR level:
rest_api_small (2KB), wide_object (3KB), deep_nesting (0.5KB)
- Full level: additionally
rest_api_medium (60KB), unicode_heavy_twitter (631KB)
Cargo.toml changes:
[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }
[[bench]]
name = "rust_bench"
harness = false
2. CI Workflow
New file: .github/workflows/bench.yml
Triggers:
push to main → run benchmarks, update gh-pages baseline
pull_request → run benchmarks, compare against main baseline, post PR comment
Job structure:
jobs:
benchmark:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- checkout (with submodules for fixtures)
- install stable rust
- cargo bench --bench rust_bench -- --output-format bencher
- benchmark-action/github-action-benchmark:
tool: cargo
output-file-path: target/criterion/output.txt
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true (main only)
comment-on-alert: true
alert-threshold: "105%" # >5% regression triggers warning
fail-on-alert: false # non-blocking, reviewer decides
gh-pages-branch: gh-pages
benchmark-data-dir-path: dev/bench
3. Makefile Integration
bench-rust: ## Run Rust criterion benchmarks
cargo bench --bench rust_bench
4. Initialization
- First merge to main auto-creates baseline in gh-pages
- PR comments show comparison table with regression highlighting
-
5% regression marked yellow/red but does not block merge
Acceptance Criteria
References
Background
qjson positions itself as a high-performance JSON parser, but currently lacks automated performance regression detection. Benchmarks exist (
benches/lua_bench.lua) but run manually without CI enforcement.Goal
Prevent unintentional performance degradation by adding automated benchmark comparison to CI.
Scope
In Scope
benchmark-action/github-action-benchmarkgh-pagesbranchOut of Scope
Design
1. Criterion Benchmarks
File:
benches/rust_bench.rsBenchmark groups:
parse_eager- eager mode parsing (full validation)parse_lazy- lazy mode parsing (structural scan only)field_access- field access operations (get_str, get_f64, nested paths)Fixtures (based on manifest.json
citags):rest_api_small(2KB),wide_object(3KB),deep_nesting(0.5KB)rest_api_medium(60KB),unicode_heavy_twitter(631KB)Cargo.toml changes:
2. CI Workflow
New file:
.github/workflows/bench.ymlTriggers:
pushtomain→ run benchmarks, update gh-pages baselinepull_request→ run benchmarks, compare against main baseline, post PR commentJob structure:
3. Makefile Integration
4. Initialization
Acceptance Criteria
cargo benchruns criterion benchmarks covering parse_eager, parse_lazy, field access patternsReferences