1515 CARGO_TERM_COLOR : always
1616 RUST_BACKTRACE : 1
1717 # Minimum supported Rust version
18- MSRV : " 1.75 "
18+ MSRV : " 1.82 "
1919
2020jobs :
2121 # ==========================================================================
8585 # MSRV check
8686 # ==========================================================================
8787 msrv :
88- name : MSRV (${{ env.MSRV }} )
88+ name : MSRV (1.82 )
8989 runs-on : ubuntu-latest
9090 steps :
9191 - uses : actions/checkout@v4
@@ -183,6 +183,91 @@ jobs:
183183 target/${{ matrix.target }}/release/apc.exe
184184 if-no-files-found : ignore
185185
186+ # ==========================================================================
187+ # Benchmarks
188+ # ==========================================================================
189+ benchmark :
190+ name : Benchmark
191+ runs-on : ubuntu-latest
192+ steps :
193+ - uses : actions/checkout@v4
194+
195+ - name : Install Rust
196+ uses : dtolnay/rust-toolchain@stable
197+
198+ - name : Cache cargo
199+ uses : Swatinem/rust-cache@v2
200+
201+ - name : Run benchmarks
202+ run : cargo bench --bench benchmarks -- --noplot --save-baseline ci
203+
204+ - name : Check benchmark results
205+ run : |
206+ echo "Benchmark completed successfully!"
207+ echo "Key benchmark results:"
208+ echo "======================"
209+ # Parse and display key metrics from Criterion output
210+ for dir in target/criterion/*/new; do
211+ if [ -d "$dir" ]; then
212+ bench_name=$(basename $(dirname "$dir"))
213+ if [ -f "$dir/estimates.json" ]; then
214+ mean=$(grep -o '"point_estimate":[0-9.]*' "$dir/estimates.json" | head -1 | cut -d: -f2)
215+ if [ -n "$mean" ]; then
216+ # Convert to human-readable format
217+ if (( $(echo "$mean < 1000" | bc -l) )); then
218+ echo "$bench_name: ${mean}ns"
219+ elif (( $(echo "$mean < 1000000" | bc -l) )); then
220+ echo "$bench_name: $(echo "scale=2; $mean/1000" | bc)µs"
221+ else
222+ echo "$bench_name: $(echo "scale=2; $mean/1000000" | bc)ms"
223+ fi
224+ fi
225+ fi
226+ fi
227+ done
228+
229+ - name : Verify performance thresholds
230+ run : |
231+ # Define performance thresholds (in nanoseconds)
232+ # These are based on current benchmark results with 50% margin
233+ declare -A THRESHOLDS=(
234+ ["detector_detect"]=25000000 # 25ms max (current ~14µs)
235+ ["detector_detect_with_custom_vars"]=25000000 # 25ms max
236+ ["config_parsing_full"]=20000000 # 20ms max (current ~9µs)
237+ ["config_parsing_minimal"]=10000000 # 10ms max (current ~4µs)
238+ ["config_default"]=2000000 # 2ms max (current ~550ns)
239+ ["config_validation"]=1000000 # 1ms max (current ~33ns)
240+ )
241+
242+ FAILED=0
243+ for bench_name in "${!THRESHOLDS[@]}"; do
244+ threshold=${THRESHOLDS[$bench_name]}
245+ estimates_file="target/criterion/$bench_name/new/estimates.json"
246+
247+ if [ -f "$estimates_file" ]; then
248+ mean=$(grep -o '"point_estimate":[0-9.]*' "$estimates_file" | head -1 | cut -d: -f2)
249+ if [ -n "$mean" ]; then
250+ # Compare using bc for floating point
251+ if (( $(echo "$mean > $threshold" | bc -l) )); then
252+ echo "❌ REGRESSION: $bench_name exceeded threshold!"
253+ echo " Current: ${mean}ns, Threshold: ${threshold}ns"
254+ FAILED=1
255+ else
256+ echo "✓ $bench_name: ${mean}ns (threshold: ${threshold}ns)"
257+ fi
258+ fi
259+ fi
260+ done
261+
262+ if [ $FAILED -eq 1 ]; then
263+ echo ""
264+ echo "Performance regression detected! Please investigate."
265+ exit 1
266+ fi
267+
268+ echo ""
269+ echo "All benchmarks within acceptable thresholds."
270+
186271 # ==========================================================================
187272 # Security audit
188273 # ==========================================================================
@@ -233,7 +318,7 @@ jobs:
233318 # ==========================================================================
234319 ci-success :
235320 name : CI Success
236- needs : [fmt, clippy, test, msrv, docs, build, security, coverage]
321+ needs : [fmt, clippy, test, msrv, docs, build, benchmark, security, coverage]
237322 runs-on : ubuntu-latest
238323 if : always()
239324 steps :
@@ -245,6 +330,7 @@ jobs:
245330 [[ "${{ needs.msrv.result }}" != "success" ]] || \
246331 [[ "${{ needs.docs.result }}" != "success" ]] || \
247332 [[ "${{ needs.build.result }}" != "success" ]] || \
333+ [[ "${{ needs.benchmark.result }}" != "success" ]] || \
248334 [[ "${{ needs.security.result }}" != "success" ]] || \
249335 [[ "${{ needs.coverage.result }}" != "success" ]]; then
250336 echo "One or more jobs failed"
0 commit comments