Benchmark Report — Decision Intelligence (v1.6.0)¶
Date: 2026-07-08
Package: mineproductivity.decision (software v1.6.0)
Scenarios: benchmark/scenarios/decision/
Environment: Windows 11 (AMD64), CPython 3.12.10, mineproductivity editable-installed. Single process, single thread, no other load control — these are reference numbers for order-of-magnitude regression tracking, not a controlled lab measurement.
Both scenarios are standalone scripts (the mineproductivity.benchmark harness package is not yet implemented — see benchmark/README.md); re-run them with:
python benchmark/scenarios/decision/rule_engine_throughput.py
python benchmark/scenarios/decision/audit_trail_latency.py
1. RuleEngine.evaluate() throughput¶
Policy/rule-count scale spans "one policy" (10 rules) through "every policy a site owns, evaluated as one batch" (250 rules). Half the rules trigger, half do not, and one rule always raises, so the per-rule isolation machinery (design spec 07 §10) is inside the measured window; the isolation warning log line is silenced during measurement so console I/O is not what gets timed.
| rules per evaluation | iterations | total (s) | evaluations/s | rules/s |
|---|---|---|---|---|
| 10 | 2,000 | 0.014 | 138,953 | 1,389,526 |
| 50 | 1,000 | 0.038 | 26,352 | 1,317,599 |
| 250 | 200 | 0.037 | 5,402 | 1,350,519 |
Reading: throughput in rules/s is flat (~1.3–1.4 M rules/s) across a 25× spread in rules-per-evaluation — evaluate() scales linearly in rule count with no super-linear overhead, and a full 250-rule site-wide batch evaluates in ~185 µs. Rule evaluation cost is dominated by the already-small DecisionContext, corroborating the design spec §35 performance posture (no independent large-scale computation in decision).
2. DecisionAuditTrail append/query latency¶
Trail sizes span "a busy week" (10³) through "a year, never pruned" (10⁵), one decision per equipment per shift across a large fleet. query() figures are means over 20 calls.
| entries | append (µs/entry) | query all (ms) | query by scope (ms) | scope matches |
|---|---|---|---|---|
| 1,000 | 0.36 | 0.01 | 0.62 | 500 |
| 10,000 | 0.34 | 0.06 | 7.17 | 5,000 |
| 100,000 | 0.31 | 1.34 | 70.98 | 50,000 |
Reading: per-entry record() cost is flat (~0.3 µs) across a 100× size spread — the O(1)-append proof the implementation checklist requires. query() grows linearly with trail size, which is audit.py's own disclosed reference-implementation posture (snapshot + linear scan; a scope-indexed structure is a documented future option requiring no public-API change): at the one-year/100k-entry scale a scope-filtered query costs ~71 ms, acceptable for audit/reporting use and far off the rule-evaluation hot path.
Regression guidance¶
Re-run both scenarios before each release touching decision; investigate if rules/s drops below ~500k, append cost exceeds ~2 µs/entry, or either query latency grows more than ~5× at equal scale on comparable hardware.