Skip to content

Benchmarking

TL;DR

The benchmark CLI exercises the MENoBiS pipeline with PA-geographic non-binary networks: generate constraints, fit, sample, filter, and measure time, memory, convergence, and precision.

Canonical regime

Use the dense regime by default: average_degree = N/5 and events_per_edge = 8.0. Sparse and saturated regimes are stress tests.

Benchmark matrix

Dimension Values
Node counts user-selected, commonly 100 and 1000 first
Families ME, B, W; W zero-inflated routes need extra care
Constraints strength, strength-cost, strength-edges, strength-degree
Self-loops no-self-loops default; self-loops optional
Known-pair fraction 0%, 2%, or explicit stress values
Regime dense default, sparse, saturated

Regimes

Regime Parameters Use
sparse average_degree=3.0, events_per_edge=3.0 stress nearly-binary occupations
dense average_degree=N/5, events_per_edge=8.0 default scientific benchmark
saturated average_degree=0.85*(N-1), events_per_edge=8.0 stress boundary degrees

Metrics collected

Metric How measured
wall time time.perf_counter()
CPU time time.process_time()
parallelism factor CPU / wall ratio
Python memory tracemalloc peak delta
RSS memory /proc/self/status VmRSS delta
convergence result.converged, status, iterations
precision constraint residuals

Commands

uv run python -m benchmarks all --nodes 100,1000 --regime dense

uv run python -m benchmarks all --nodes 1000 --families me,b \
  --regime dense --known-pairs 0.0,0.02 --self-loops

uv run python -m benchmarks compare --nodes 500 --families me,b \
  --constraints strength-degree

Interpreting results

Observation Meaning
parallel_factor > 1.5 Rust parallelism is active
converged=False inspect residuals before scientific use
high residual, low iterations likely feasibility or scaling issue
high iterations, low residual tolerance may be stricter than needed

Conformance checks covered

Area Benchmark expectation
family separation ME, B, and W use different expectation equations
coordinate costs costs are computed on demand from projected XY
partial fitting frozen pairs are subtracted before fitting free support
sparse memory masks and outputs stay sparse; no public dense cost/rate matrix
filtering calibration false-positive rates are measured on null samples

Partial fitting

Partial benchmarks freeze a fraction of observed pairs as known and fit the free subproblem. Reports include convergence and timing for the excess constraints. Start with 2% known pairs; increase only after validating memory and runtime.

Output format

Results are JSON arrays. Each row contains stage, metrics, and precision fields. See benchmarks/results/ for stored runs and Scalability for a plot built from repository results.