Performance
The numbers below are the benchmark results committed in benchmarks/. They are one run on one machine, and the files do not record which machine, so read them as orders of magnitude and relative costs, not as a promise about your hardware. Pull requests are not judged against them (see Regression gate).
Rust core (criterion)
Section titled “Rust core (criterion)”benchmarks/latest_benchmarks.json: 7 benchmarks, collected on 2026-02-07 at commit 8135e47. Times are criterion’s mean per iteration with its 95% confidence interval.
| Benchmark | What it measures | Mean (ms) | 95% CI (ms) | Source |
|---|---|---|---|---|
structural_breaks_get_sadf_sm_power | structural_breaks::get_sadf, sm_power model with constant, on 320 log prices, minimum window 20, 5 fixed lags | 602.0 | 600.0–604.0 | perf_hotspots.rs |
synthetic_ticker_seq_bootstrap_2k_600 | sampling::seq_bootstrap: 240 draws from an indicator matrix of 600 labels over 2,000 bars | 383.9 | 360.3–409.8 | synthetic_ticker_pipeline.rs |
synthetic_ticker_pipeline_end_to_end | EWMA, VaR/ES/CDaR, a 3×3 covariance and portfolio variance, and a 200-draw sequential bootstrap (360 labels over 1,200 bars) on 20,000 prices, in one pass | 61.72 | 60.90–62.48 | synthetic_ticker_pipeline.rs |
bet_sizing_bet_size_reserve_fit | bet_sizing::bet_size_reserve_full on 500 synthetic events: fits the EF3M mixture (100 runs) and sizes every bet | 18.75 | 17.82–19.81 | perf_hotspots.rs |
synthetic_ticker_risk_metrics_var_es_cdar | RiskMetrics value at risk, expected shortfall and conditional drawdown at risk (5%) on 119,999 returns | 8.01 | 7.50–8.60 | synthetic_ticker_pipeline.rs |
synthetic_ticker_ewma_100k | util::fast_ewma::ewma, window 64, on 100,000 prices | 4.72 | 4.69–4.75 | synthetic_ticker_pipeline.rs |
bet_sizing_bet_size_reserve_reuse_fit | bet_sizing::bet_size_reserve on the same 500 events, reusing already-fitted mixture parameters | 0.278 | 0.274–0.284 | perf_hotspots.rs |
benchmarks/baseline_benchmarks.json holds the same numbers: the baseline was last refreshed from this run.
Benchmarks that exist in crates/openquant/benches/ but are not in benchmarks/benchmark_manifest.json, so are neither committed here nor gated: hpc_parallel/serial_linear (hpc_parallel_scaling.rs), hpc_parallel/threaded_linear (hpc_parallel_scaling.rs), hpc_parallel/threaded_nested (hpc_parallel_scaling.rs), streaming_hpc/scaling/* (streaming_hpc_scaling.rs). Run them with cargo bench -p openquant --bench <file stem>.
Python data layer
Section titled “Python data layer”benchmarks/data_processing/latest.json, written by python/benchmarks/benchmark_data_processing.py: 4 symbols × 100,000 rows (400,000 rows), 5 iterations per function. The file records neither a date nor a commit. just py-bench-data regenerates it (with 200,000 rows per symbol, not the size committed here).
| Function | Rows | Mean (ms) | p95 (ms) | Rows/s | MB/s |
|---|---|---|---|---|---|
clean_ohlcv | 400,000 | 431.8 | 430.2 | 926,317 | 48.2 |
data_quality_report | 400,000 | 202.2 | 205.0 | 1,977,855 | 102.8 |
align_calendar | 400,000 | 487.7 | 485.1 | 820,180 | 49.2 |
load_ohlcv_csv | 400,000 | 234.6 | 235.6 | 1,704,667 | 120.3 |
load_ohlcv_parquet | 400,000 | 458.7 | 468.5 | 872,087 | 4.9 |
There is no committed benchmarks/data_processing/baseline.json, so just py-bench-data-compare has nothing to compare against until one is made, and no CI job runs these benchmarks.
Regression gate
Section titled “Regression gate”.github/workflows/benchmark-regression.yml runs on pull requests that touch crates/openquant/, the workspace manifests, the toolchain pin or the benchmark scripts. It builds the pull request’s merge base and its head, runs the perf_hotspots and synthetic_ticker_pipeline benches on both on the same runner, and fails if a benchmark’s mean slowed down by more than 35% (scripts/check_bench_thresholds.py), or by more than its entry in benchmarks/threshold_overrides.json. A benchmark that stops producing a result fails the gate too. Comparing base and head back to back removes the machine-to-machine variation that made a gate against the committed baseline fail on unrelated changes. Because the workflow is path-filtered, it is not suitable as a required status check.
| Benchmark | Allowed slowdown |
|---|---|
structural_breaks_get_sadf_sm_power | 35% |
bet_sizing_bet_size_reserve_fit | 35% |
bet_sizing_bet_size_reserve_reuse_fit | 55% |
synthetic_ticker_ewma_100k | 35% |
synthetic_ticker_risk_metrics_var_es_cdar | 35% |
synthetic_ticker_seq_bootstrap_2k_600 | 35% |
synthetic_ticker_pipeline_end_to_end | 50% |
Reproduce
Section titled “Reproduce”just bench-all # cargo bench -p openquant --bench perf_hotspots --bench synthetic_ticker_pipelinejust bench-collect # target/criterion -> benchmarks/latest_benchmarks.json (manifest only)just bench-check # latest vs the committed baseline, with the thresholds CI usesjust py-bench-data # Python data-layer benchmarks -> benchmarks/data_processing/latest.jsonpython3 scripts/docs/generate_site_pages.py --write # re-render this pageRefresh benchmarks/baseline_benchmarks.json only in a pull request that says why; a slowdown and a new baseline in the same change hides the slowdown.