Benchmark Models

What the Rust engine is worth, measured on two models: a scalar one over time and an arrayed one over its width.
Keywords

benchmark, performance, rust, execution engine, system dynamics, bptk, bptk-py, python

Benchmark Models

Choosing an engine is a decision about speed, and speed is the one thing a documentation page should not ask you to take on faith. Two models are measured here in full - the code to reproduce them, the numbers they produced, and what those numbers do not say.

  • A scalar model over time - an SIR epidemic with vaccination and a hospital-capacity feedback, from 400 to 400,000 timesteps. The question it answers: how much does a longer run gain?
  • An arrayed model over its width - a workforce chain whose vector grows from 3 seniority levels to 200. The question it answers: what does a wider model cost, which is the axis a scalar model does not have.

How both are measured

  • Through the ordinary API. Both runs call run_scenarios; only the backend argument differs. Nothing is measured that a user would not also pay.
  • Median of three runs, each on a freshly built model, so no result cache carries over.
  • Both engines are compared, not just timed: every equation of every run is checked against the other engine, and the largest deviation is reported with the timings.

Two things to know before you compare

Build the engine in release mode. maturin develop produces a debug build, roughly five times slower than the release build that ships in the wheel. Benchmark against maturin develop --release, or against an installed pip install BPTK-Py. A debug build is the most common reason a benchmark disappoints.

Your milliseconds will differ; the ratio and the shape are what to compare. These numbers come from one machine - an Apple M3 on Python 3.13 - and a laptop on battery will produce different ones. What carries over is how the ratio moves as the model grows.

In a browser there is nothing to benchmark. Neither of these pages runs its own code: the compiled engine has no place to run under Emscripten, so a page that measured itself in your browser would time the Python engine twice and report a speedup of 1.0.