Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Comparative Measurements

Comparative performance measurements against commonly used quantum simulators. These results are intended to make performance characteristics reproducible and transparent across representative workloads, not to rank projects: each simulator makes different trade-offs, and a ratio here describes one workload on one host under the controls listed below.

Every simulator replays the same gate list for each circuit, built from the prism_q::circuits generators and hashed so a rerun can prove it did the same work. The timed region is: execute the circuit and materialize the full 2^n probability vector; building the circuit from the gate list is excluded on every side. Ratios are the comparator's median over PRISM-Q's median, so a ratio above 1.00x means PRISM-Q finished sooner and below 1.00x means the comparator did; a ratio within 10% of 1.00x is reported as within band, because cross-process timing noise on one host is of that order.

Host and versions

FieldValue
CPUIntel(R) Core(TM) i7-6700K CPU @ 4.00GHz
Cores4 physical, 8 logical
RAM31.9 GB
OSWindows 10
rustc (PRISM-Q)1.97.0, features parallel, profile release
rustc (Spinoza, qip)1.99.0-nightly, profile release
C++ compiler (QuEST)MSVC 19.38.33145.0
Python3.14.0
Commit9324ed6c019b7f36f29cd28ec46824afaa354910 (dirty tree)
Threads8 on every simulator
Iterations5 timed per circuit after one warmup
SimulatorVersionSettings
PRISM-Q (auto dispatch)0.33.0BackendKind::Auto, fusion on, double precision, RAYON_NUM_THREADS pinned
Qiskit Aer (statevector)0.17.2method=statevector, fusion on (default), double precision, max_parallel_threads pinned
Qiskit Aer (automatic)0.17.2method=automatic, fusion on (default), double precision, max_parallel_threads pinned
qsim (qsimcirq)0.22.1QSimOptions defaults (max_fused_gate_size 2), cpu_threads pinned; single precision, the only precision qsim offers
QuEST (OpenMP)v4.3.0static library, double precision, OpenMP on, OMP_NUM_THREADS pinned
Spinoza0.5.1 (git f900971)default double feature, Config.threads pinned
RustQIP (qip)1.5.0LocalBuilder, parallel feature, RAYON_NUM_THREADS pinned

Per-call overhead of driving a comparator from Python on a one-gate circuit, recorded so small rows can be read correctly: aer-statevector 549 us, aer-automatic 492 us, qsim 130 us.

Results

CircuitQubitsGatesPRISM-Qaer-statevectorratioaer-automaticratioqsimratioquestratiospinozaratioqipratiomax TVD
ghz161618 us3.9 ms222.10x1.2 ms67.55x3.0 ms171.15x3.0 ms170.16x1.7 ms96.86x8.7 ms492.09x1.7e-08
qft161442.5 ms26.3 ms10.66x26.5 ms10.77x13.9 ms5.64x17.6 ms7.14x14.8 ms6.00x168.8 ms68.52x1.9e-15
hea162353.7 ms29.2 ms7.96x29.8 ms8.14x18.6 ms5.07x34.1 ms9.30x104.1 ms28.40x69.6 ms19.00x5.1e-07
qv1610246.1 ms91.2 ms14.98x90.0 ms14.78x57.2 ms9.40x133.5 ms21.92x347.3 ms57.02x285.7 ms46.92x1.2e-06
ghz20201.3 ms36.3 ms27.47x4.4 ms3.37x47.2 ms35.71x41.5 ms31.45x24.7 ms18.73x147.4 ms111.61x1.7e-08
qft2022052.8 ms193.5 ms3.66x201.1 ms3.81x156.0 ms2.95x286.1 ms5.42x244.4 ms4.63x3.00 s56.73x2.2e-15
hea2029534.4 ms178.5 ms5.19x177.1 ms5.15x96.1 ms2.79x474.8 ms13.80x1.56 s45.41x992.1 ms28.84x6.2e-07
qv20160072.3 ms606.6 ms8.39x592.4 ms8.19x200.4 ms2.77x1.84 s25.39x6.44 s89.02x4.52 s62.43x1.6e-06
ghz242420.2 ms435.2 ms21.54x23.0 ms1.14x648.4 ms32.09x587.7 ms29.08x411.9 ms20.38x2.20 s109.06x1.7e-08
qft243121.01 s2.48 s2.44x2.45 s2.42x3.75 s3.69x4.32 s4.26x4.57 s4.51x58.33 s57.51x2.6e-15
hea24355593.6 ms2.12 s3.57x2.10 s3.54x1.83 s3.09x8.38 s14.13x23.53 s39.64x16.56 s27.90x6.6e-07
qv2423041.45 s5.66 s3.91x5.64 s3.89x3.80 s2.62x50.34 s34.73x130.22 s89.84x114.49 s78.99x1.8e-06

Reading the ratios: the comparators differ in design, and the design explains most of a gap. QuEST and Spinoza apply every gate as its own pass over the state and carry no gate fusion, so their time grows with the gate count; PRISM-Q, Aer and qsim fuse gates before execution, which pays most on the deep families (HEA, QV). Under automatic, Aer routes a Clifford circuit (GHZ) to its stabilizer method, as PRISM-Q routes it to its stabilizer backend, so that row compares two tableau simulations plus the dense read-out rather than two statevector runs. The GHZ rows at every size are dominated by materializing the 2^n probability vector, not by the gates. The QFT rows run the expanded textbook sequence on every simulator, PRISM-Q included, so PRISM-Q's block FFT path (which the Benchmarks page measures through the generator's QftBlock) is not exercised here and its QFT times are higher than on that page.

Summary

Counted over circuits with at least 16 qubits. A row where the comparator did not run is not counted.

ComparatorPRISM-Q soonerWithin bandComparator soonerMedian ratioRange
aer-statevector12008.17x2.44x to 222.10x
aer-automatic12004.52x1.14x to 67.55x
qsim12004.38x2.62x to 171.15x
quest120018.02x4.26x to 170.16x
spinoza120034.02x4.51x to 96.86x
qip120059.97x19.00x to 492.09x

Equivalence

Every simulator reproduced the reference probability vector (aer-statevector) to within 1e-05 total variation distance on every circuit. The tolerance separates a wrong answer, which lands near 1e-1, from rounding; the max TVD column shows the measured distance, and a value near 1e-6 is the single-precision comparator.

Reproducing

The harness, its adapters, and the build steps for each comparator are in comparison/README.md in the repository. The run that produced this page is committed as comparison/results/reference-<host>.json; --check against it re-runs the comparison and exits non-zero when a circuit hash, an output, or a verdict no longer matches.

python comparison/run_comparison.py --iterations 5 --qubits 16,20,24 \
  --out comparison/results/run.json --markdown comparison/results/run.md

The Benchmark Methodology page states the controls these numbers were taken under and what a comparison needs before it can be cited.