Benchmarks

All twenty-one rows, both platforms.

These benchmarks are not a claim that DominScript is generally faster than Python, and the table is not a race. Python is there as a reference point: a language everyone can place, measured on the same machine with the same programs. Every row links to the two programs below; the runner writes results.json; rows are added, never dropped.

LinuxAMD Ryzen 9 8945HX · Linux x86-64 · GCC Release build · CPython 3.12.3 · package 512, 2026-10-06, 7 interleaved runs
Same benchmarks, Linux DominScript, ms Python 3, ms Elapsed time, shorter is better DS / Py
Recursive Fibonacci(28)pure script · recursion — a small integer function calling itself 9 24
DS
Py
0.38×
Arithmetic loop, 10M iterationspure script · tight integer loop 102 451
DS
Py
0.23×
Sieve of Eratosthenes (N=5M)plugin · blob.FillStep + CountByte against the Python slice idiom 7 21
DS
Py
0.33×
Mandelbrot 200×200, 200 iterpure script · nested double arithmetic 44 116
DS
Py
0.38×
N-body, 5 bodies, 20k stepspure script · struct-member double arithmetic with a square root per pair (num.Sqrt) 32 74
DS
Py
0.43×
Fannkuch-redux, n=8pure script · integer array permutation and swaps 26 29
DS
Py
0.90×
String find, 3 kB × 200kplugin-heavy · str plugin: one-pass SIMD search (AVX2/SSE2) 7 44
DS
Py
0.16×
JSON parse + read, 30kplugin-heavy · json plugin 22 38
DS
Py
0.58×
SHA-256, 1 kB × 20kplugin-heavy · crypto plugin (SHA-NI when the CPU has it, portable C otherwise) vs. Python's OpenSSL-backed hashlib 11 11
DS
Py
1.00×
Plugin call, 1M × str.Lenplugin-heavy · the price of one native call from script · a verb the plugin declares pure runs as a loop-machine op 12 24
DS
Py
0.50×
Map put + get, 200k keysplugin-heavy · map plugin: hashing plus a call per operation · Python: dict 43 53
DS
Py
0.81×
Regex match, 100k linesplugin-heavy · regex plugin (Spencer engine) vs. Python's re 13 19
DS
Py
0.68×
Packet data path, 200k framesworkload · receive buffer → slice → typed view → fields → decision · Python: bytearray + struct.unpack_from 8 28
DS
Py
0.29×
Log lines, 100kworkload · build, find, slice, parse, format · Python: str methods 22 40
DS
Py
0.55×
Header parsing by hand, 200k headersworkload · IPv4 + TCP headers in network byte order: byte reads, shifts and masks for every field · Python: struct.unpack_from and the same masks 100 114
DS
Py
0.88×
Header parsing with a schema, 200k headersworkload · the same headers read through a packet big schema with bit fields · Python: the same program as the row above 59 114
DS
Py
0.52×
for loop, 3M iterationsordinary style · the most common loop form 28 119
DS
Py
0.24×
Local declared in the loop body, 3M iterationsordinary style · a numeric local declared and initialised inside the hot loop (i64 $T = ...;) 33 130
DS
Py
0.25×
Helper function called in the loop, 3M iterationsordinary style · a small integer helper function called once per iteration 40 163
DS
Py
0.25×
Integer × double in the loop, 3M iterationsordinary style · an integer variable used in floating-point arithmetic ($Acc + $I * 0.5) 26 69
DS
Py
0.38×
Packet data path organised into a functionordinary style · the packet workload with the per-frame logic moved into a function (HandleFrame(ref blob)) 11 34
DS
Py
0.32×
DominScriptCPython 3.12.3median in-script elapsed time of 7 runs (process startup excluded), same machine (AMD Ryzen 9 8945HX, Linux x86-64), all twenty-one rows measured 2026-10-01 on the current tree (idiomatic Python twins) · bars are scaled per row · ratio < 1 means DominScript is faster

Why CPython, and not PyPy. Both columns are interpreters: CPython runs bytecode, DominScript walks its tree and specialises hot loops into a small op machine — neither emits native code. PyPy would win most of these rows, as any JIT would; it is a different category (runtime compilation to machine code) and a different trade-off (startup, memory, embedding). The comparison here is interpreter against interpreter. The benchmark sources and the Python twins are in the package’s benchmarks/ folder; the runner and the numbers are reproducible.

Windowsthe same machine · Windows 11 x86-64 · mingw-w64 GCC 13 build · package 512, 2026-10-06, 7 runs, CPython 3.14.7 · both columns from the same run
Same benchmarks, Windows DominScript, ms Python 3, ms Elapsed time, shorter is better DS / Py
Recursive Fibonacci(28)pure script · recursion — a small integer function calling itself 8 34
DS
Py
0.24×
Arithmetic loop, 10M iterationspure script · tight integer loop 102 520
DS
Py
0.20×
Sieve of Eratosthenes (N=5M)plugin · blob.FillStep + CountByte against the Python slice idiom 6 21
DS
Py
0.29×
Mandelbrot 200×200, 200 iterpure script · nested double arithmetic 44 154
DS
Py
0.29×
N-body, 5 bodies, 20k stepspure script · struct-member double arithmetic with a square root per pair (num.Sqrt) 28 110
DS
Py
0.25×
Fannkuch-redux, n=8pure script · integer array permutation and swaps 26 38
DS
Py
0.68×
String find, 3 kB × 200kplugin-heavy · str plugin: one-pass SIMD search (AVX2/SSE2) 7 53
DS
Py
0.13×
JSON parse + read, 30kplugin-heavy · json plugin 30 41
DS
Py
0.73×
SHA-256, 1 kB × 20kplugin-heavy · crypto plugin (SHA-NI when the CPU has it, portable C otherwise) vs. Python's OpenSSL-backed hashlib 13 14
DS
Py
0.93×
Plugin call, 1M × str.Lenplugin-heavy · the price of one native call from script · a verb the plugin declares pure runs as a loop-machine op 13 28
DS
Py
0.46×
Map put + get, 200k keysplugin-heavy · map plugin: hashing plus a call per operation · Python: dict 42 54
DS
Py
0.78×
Regex match, 100k linesplugin-heavy · regex plugin (Spencer engine) vs. Python's re 24 22
DS
Py
1.09×
Packet data path, 200k framesworkload · receive buffer → slice → typed view → fields → decision · Python: bytearray + struct.unpack_from 8 32
DS
Py
0.25×
Log lines, 100kworkload · build, find, slice, parse, format · Python: str methods 25 38
DS
Py
0.66×
Header parsing by hand, 200k headersworkload · IPv4 + TCP headers in network byte order: byte reads, shifts and masks for every field · Python: struct.unpack_from and the same masks 121 124
DS
Py
0.98×
Header parsing with a schema, 200k headersworkload · the same headers read through a packet big schema with bit fields · Python: the same program as the row above 63 124
DS
Py
0.51×
for loop, 3M iterationsordinary style · the most common loop form 29 122
DS
Py
0.24×
Local declared in the loop body, 3M iterationsordinary style · a numeric local declared and initialised inside the hot loop (i64 $T = ...;) 34 133
DS
Py
0.26×
Helper function called in the loop, 3M iterationsordinary style · a small integer helper function called once per iteration 44 173
DS
Py
0.25×
Integer × double in the loop, 3M iterationsordinary style · an integer variable used in floating-point arithmetic ($Acc + $I * 0.5) 27 83
DS
Py
0.33×
Packet data path organised into a functionordinary style · the packet workload with the per-frame logic moved into a function (HandleFrame(ref blob)) 10 39
DS
Py
0.26×
DominScriptCPython 3.14.7median in-script elapsed time of 7 runs (process startup excluded), the same machine booted into Windows 11 x86-64, mingw-w64 GCC 13 build (-O3), current tree, all twenty-one rows measured 2026-10-01 (idiomatic Python twins) · bars are scaled per row · ratio < 1 means DominScript is faster
interpreter microbenchmarks

Where the time goes, row by row

Where the loop body is arithmetic — integer or double — indexes a typed array or reads struct members, DominScript runs at a quarter to a half of CPython’s time on both platforms: the binder compiles provably-numeric statements and whole numeric loops into a small register machine, so those loops do not walk the tree. The four style rows are habits rather than algorithms — a for loop, a local declared inside the loop, a small helper, an integer in floating-point arithmetic — and they run at the same ratio; they are in the table so that a regression cannot hide.

Where the work is done inside a plugin, the plugin’s C code sets the pace: JSON and SHA-256 sit at 0.6–1.1×, map and regex at 0.6–0.8×, the one-pass SIMD string search at 0.1–0.2×. Python wins one row on each platform, and neither is the interpreter: SHA-256 on Linux at parity (the same C kernel on both sides, 11 ms each) and the regex row on Windows at 1.09× (the regex engine’s own allocations on the mingw allocator; the same row is 0.68× on Linux) — and SHA-256 at parity (the same C kernel on both sides, 11 ms each). On Windows every DominScript row is ahead of the Python column measured there, the regex row included (14 ms, 0.64×) — an earlier Windows run had it at 1.09×

The two workload shapes this language exists for: the packet data path — socket → buffer → struct → decision — runs at 0.25–0.30× in both its forms, the log-lines row at 0.55–0.63×. The two header-parsing rows read together: the same IPv4 + TCP headers parsed by hand sit at 0.88–0.92×, read through a packet big schema with bit fields at 0.48–0.50× — the readable form is the fast one.

The two tables are the same tree built with gcc on Linux and with mingw-w64 on the same machine booted into Windows, measured on the same day. The DominScript column is nearly the same on both (Fibonacci 9 vs 8 ms, the arithmetic loop 102 vs 102, N-body 32 vs 28); CPython is slower on Windows, so the ratios look better there; the string/heap rows are slower on Windows on the DominScript side (header parsing by hand 121 vs 100 ms, JSON 30 vs 22, regex 24 vs 13), the mingw allocator’s known cost. Twenty of the twenty-one rows are ahead of Python on both platforms. Earlier versions of this page published the same rows with worse ratios — several were behind Python, and they were shown as such; the rows never changed, the implementation did, and the set behind Python shrank with each round — today it is one row per platform. That is not cherry-picking: no row has ever been removed because it looked bad.

Every benchmark script for both languages is in the repository, the four workload rows included, and the runner writes results.json. Rows are added, never dropped. The two programs behind every row →