This document records comparative performance of the DByte VM against Python 3.12.9 on a local Windows release-build test machine.
Safe public claim:
DByte v1.9.2 outperforms Python 3.12.9 across DByte's measured benchmark suite on a Windows release-build test machine.
This is limited to the benchmark suite below. It is not a claim that DByte is faster than Python for every workload, platform, or implementation style.
v2.0.0 is a public alpha packaging and documentation release based on the
v1.9.2 engine plus installer, examples, and release artifacts. No new
performance claim is introduced by v2.0.0.
Engine: tree / vm
Build: release
Machine: local Windows machine
Date: 2026-05-10
| Benchmark | Tree | VM | Notes |
|---|---|---|---|
| loop_sum | 279.43 ms | 179.08 ms | VM faster |
| function_call | 663.81 ms | 366.83 ms | VM much faster |
| bytes_find | 15.00 ms | 12.77 ms | VM slightly faster |
| buffer_replace | 97.60 ms | 136.28 ms | VM slower; investigate native call path |
| binary_read_u32 | 1480.64 ms | 1491.92 ms | Both slow; heavy native call overhead |
| patch_workflow | 288.14 ms | 386.10 ms | VM slower due to find/replace combo |
- VM is significantly faster on function calls and arithmetic-heavy code.
- VM is consistently slower on native function calls (
buffer_replace,binary_read_u32). binary_read_u32shows extreme overhead for both engines.- Suspected bottleneck: Native function dispatch and argument passing in VM.
Engine: vm
Build: release
Date: 2026-05-10
Optimizations: Replaced string-based module member lookups with NativeFnId enum and Rc<ModuleValue>, removed Vec<Value> allocations in native argument passing by using stack slices &[Value], and avoided BytecodeFunction cloning in dispatch path.
| Benchmark | VM Before | VM After | Improvement |
|---|---|---|---|
| loop_sum | 179.08 ms | 97.71 ms | 1.8x faster |
| function_call | 366.83 ms | 253.96 ms | 1.4x faster |
| bytes_find | 12.77 ms | 12.30 ms | 1.03x faster |
| buffer_replace | 136.28 ms | 22.93 ms | 5.9x faster |
| binary_read_u32 | 1491.92 ms | 155.40 ms | 9.6x faster |
| patch_workflow | 386.10 ms | 59.19 ms | 6.5x faster |
Version: v1.2.0
Build: release
Python: 3.12.9
Date: 2026-05-10
Optimizations: Added typed int bytecode (CONST_I64, LOAD_LOCAL_I64, STORE_LOCAL_I64, ADD_I64, comparisons) and VM intrinsic opcodes for std.binary.u32_le, std.buffer.find, and std.buffer.replace.
| Benchmark | Tree | VM v1.2.0 | Python | Python / DByte VM |
|---|---|---|---|---|
| loop_sum | 252.69 ms | 107.07 ms | 34.12 ms | 0.32x |
| function_call | 642.62 ms | 226.93 ms | 53.73 ms | 0.23x |
| bytes_find | 14.18 ms | 11.69 ms | 1.04 ms | 0.10x |
| buffer_replace | 88.26 ms | 13.42 ms | 16.54 ms | 1.24x |
| binary_read_u32 | 1303.70 ms | 73.59 ms | 114.61 ms | 1.53x |
| patch_workflow | 249.37 ms | 28.73 ms | 40.51 ms | 1.14x |
- DByte VM beats Python on the low-level binary workloads measured here:
binary_read_u32,buffer_replace, andpatch_workflow. - Python is still faster on pure numeric loops, function call overhead, and
bytes.find. - Next likely performance work: avoid cloning
Value::Bytesin VM locals and move more hot paths away from boxed stack values.
Version: v1.3.0
Build: release
Python: 3.12.9
Date: 2026-05-10
Optimizations: Added typed local metadata, separate i64 frame storage, and direct local int opcodes for common loop patterns (ADD_LOCAL_I64, ADD_LOCAL_CONST_I64, and local-vs-constant comparisons).
| Benchmark | VM v1.2.0 | VM v1.3.0 | Python | Python / DByte VM |
|---|---|---|---|---|
| loop_sum | 107.07 ms | 26.52 ms | 36.53 ms | 1.38x |
| function_call | 226.93 ms | 190.06 ms | 47.31 ms | 0.25x |
| bytes_find | 11.69 ms | 12.37 ms | 1.04 ms | 0.08x |
| buffer_replace | 13.42 ms | 8.07 ms | 13.01 ms | 1.61x |
| binary_read_u32 | 73.59 ms | 67.85 ms | 104.53 ms | 1.54x |
| patch_workflow | 28.73 ms | 22.91 ms | 34.02 ms | 1.48x |
| int_compare_loop | n/a | 59.56 ms | 67.10 ms | 1.13x |
| loop_sum_large | n/a | 57.51 ms | 72.97 ms | 1.27x |
| nested_int_loop | n/a | 27.60 ms | 37.01 ms | 1.34x |
- DByte VM now beats Python on the measured int loop workloads that compile to direct local int opcodes.
- Function-call overhead improved modestly but still loses to Python; the remaining bottleneck is call frame setup and boxed stack argument passing.
bytes_findstill loses heavily because Python delegates the core search to optimized native code.- Binary workloads stayed within the no-regression target and improved in this run.
Version: v1.4.0
Build: release
Python: 3.12.9
Date: 2026-05-10
Optimizations: Added direct function-id bytecode (CALL_FN), typed int returns (RETURN_I64), frame capacity reuse, and a discard fast path for user function calls used as statements.
| Benchmark | VM v1.3.0 | VM v1.4.0 | Python | Python / DByte VM |
|---|---|---|---|---|
| loop_sum | 26.52 ms | 26.86 ms | 41.27 ms | 1.54x |
| function_call | 190.06 ms | 110.60 ms | 73.09 ms | 0.66x |
| function_call_int | n/a | 135.73 ms | 54.81 ms | 0.40x |
| function_call_loop_return | n/a | 127.76 ms | 62.30 ms | 0.49x |
| function_call_nested | n/a | 87.53 ms | 31.80 ms | 0.36x |
| bytes_find | 12.37 ms | 10.66 ms | 1.05 ms | 0.10x |
| buffer_replace | 8.07 ms | 8.41 ms | 15.16 ms | 1.80x |
| binary_read_u32 | 67.85 ms | 62.70 ms | 101.85 ms | 1.62x |
| patch_workflow | 22.91 ms | 24.70 ms | 38.18 ms | 1.55x |
| int_compare_loop | 59.56 ms | 59.46 ms | 69.30 ms | 1.17x |
| loop_sum_large | 57.51 ms | 52.22 ms | 74.64 ms | 1.43x |
| nested_int_loop | 27.60 ms | 27.94 ms | 35.21 ms | 1.26x |
- Direct function ids remove runtime string lookup and cut
function_callfrom roughly 190 ms to roughly 111 ms in this run. - DByte VM is still slower than Python on function-call-heavy workloads; the remaining cost is boxed stack argument passing and recursive
run_chunkcall frame execution. - Existing int-loop and low-level binary workloads stayed within the no-regression target in this measurement.
- Next likely performance work: typed argument stack/return path or a register-style call frame. Function inlining remains deferred.
Version: v1.5.0
Build: release
Python: 3.12.9
Date: 2026-05-10
Optimizations: Replaced recursive VM function execution with a VM-managed call-frame dispatch loop, installed typed int arguments directly into i64 local slots, kept RETURN_I64 on the typed return path, and added frame-dispatch guards for discard calls, generic returns, wrong arity, nested calls, and recursion depth.
Baseline note: VM v1.4.2 was re-measured from tag v1.4.2 in a temporary worktree on the same machine before recording the v1.5.0 results. Timings are noisy on this machine, so claims below are limited to the measured workload results.
| Benchmark | VM v1.4.2 | VM v1.5.0 | Python | Python / DByte VM |
|---|---|---|---|---|
| loop_sum | 26.21 ms | 30.51 ms | 33.79 ms | 1.11x |
| function_call | 115.35 ms | 112.91 ms | 50.83 ms | 0.45x |
| function_call_int | 144.40 ms | 136.15 ms | 58.16 ms | 0.43x |
| function_call_loop_return | 135.61 ms | 135.54 ms | 55.21 ms | 0.41x |
| function_call_nested | 92.50 ms | 91.06 ms | 34.54 ms | 0.38x |
| function_call_chain | n/a | 154.96 ms | 77.10 ms | 0.50x |
| function_call_many_args | n/a | 173.64 ms | 84.24 ms | 0.49x |
| bytes_find | 11.99 ms | 11.62 ms | 1.48 ms | 0.13x |
| buffer_replace | 9.52 ms | 8.95 ms | 15.32 ms | 1.71x |
| binary_read_u32 | 73.86 ms | 71.18 ms | 116.77 ms | 1.64x |
| patch_workflow | 23.06 ms | 29.28 ms | 41.06 ms | 1.40x |
| int_compare_loop | 56.26 ms | 66.78 ms | 65.13 ms | 0.98x |
| loop_sum_large | 51.67 ms | 55.31 ms | 72.56 ms | 1.31x |
| nested_int_loop | 24.59 ms | 28.50 ms | 36.58 ms | 1.28x |
- Non-recursive frame dispatch makes call execution independent from the Rust call stack and keeps the deterministic DByte recursion guard, but it is not a broad speed win yet.
function_call,function_call_int,function_call_loop_return, andfunction_call_nestedare roughly flat to slightly faster versus the local v1.4.2 baseline in this run.- DByte VM still loses to Python on function-heavy workloads. The remaining bottleneck is boxed value-stack return passing and per-instruction dispatch overhead inside small function bodies.
- Low-level binary workloads still beat Python in this run:
binary_read_u32,buffer_replace, andpatch_workflow. - Next likely performance work: typed return-to-consumer, direct call-to-local opcodes, or a typed stack/register frame for small int functions. Function inlining remains deferred until those lower-risk paths are measured.
Version: v1.5.1 Build: release Date: 2026-05-10 Optimizations: Reduced hot-path frame-dispatch overhead for typed local i64 opcodes and jump handling by avoiding repeated frame helper lookups in tight loops. Also kept the native intrinsic stack cleanup path lightweight without adding new bytecode or changing semantics.
Baseline note: VM v1.5.0 and VM v1.5.1 were measured as local release-build medians from five runs each. This machine shows meaningful timing noise, so the table is used as a regression gate rather than a broad performance claim.
| Benchmark | VM v1.5.0 median | VM v1.5.1 median | Change |
|---|---|---|---|
| loop_sum | 32.87 ms | 23.86 ms | 1.38x faster |
| loop_sum_large | 69.26 ms | 47.86 ms | 1.45x faster |
| int_compare_loop | 78.66 ms | 61.96 ms | 1.27x faster |
| nested_int_loop | 33.20 ms | 25.14 ms | 1.32x faster |
| binary_read_u32 | 80.29 ms | 80.82 ms | 0.99x |
| buffer_replace | 10.58 ms | 10.08 ms | 1.05x faster |
| patch_workflow | 29.75 ms | 27.15 ms | 1.10x faster |
| function_call | 126.65 ms | 118.79 ms | 1.07x faster |
| function_call_int | 159.45 ms | 150.27 ms | 1.06x faster |
| function_call_loop_return | 155.76 ms | 150.03 ms | 1.04x faster |
| function_call_nested | 105.70 ms | 104.19 ms | 1.01x |
- v1.5.1 recovers the int-loop regressions introduced by the v1.5 frame-dispatch structure without adding new language features or opcodes.
- Binary and patching workloads remain within the regression gate in the local median run.
- Function-call-heavy workloads improve slightly but still need the planned v1.6 direct typed return-to-local path to materially close the gap with Python.
Version: v1.6.0
Build: release
Date: 2026-05-11
Optimizations: Added CALL_FN_I64_TO_LOCAL for direct user function calls returning int into an int local, plus a VM ReturnMode::StoreI64 path so RETURN_I64 writes directly into the caller frame instead of pushing a boxed stack value and immediately storing it. The compiler fast path is conservative: direct user calls with explicit -> int only, with nested call arguments and generic/member/std calls left on the existing fallback path.
Baseline note: VM v1.6.0 was measured as local release-build medians from five runs and compared to the recorded VM v1.5.1 medians. Timings are noisy on this machine, so the table is used as a regression gate and directional performance record.
| Benchmark | VM v1.5.1 median | VM v1.6.0 median | Change |
|---|---|---|---|
| loop_sum | 23.86 ms | 21.03 ms | 1.13x faster |
| loop_sum_large | 47.86 ms | 41.09 ms | 1.16x faster |
| nested_int_loop | 25.14 ms | 20.88 ms | 1.20x faster |
| binary_read_u32 | 80.82 ms | 67.01 ms | 1.21x faster |
| buffer_replace | 10.08 ms | 8.88 ms | 1.14x faster |
| patch_workflow | 27.15 ms | 23.46 ms | 1.16x faster |
| function_call | 118.79 ms | 106.17 ms | 1.12x faster |
| function_call_int | 150.27 ms | 123.07 ms | 1.22x faster |
| function_call_loop_return | 150.03 ms | 126.05 ms | 1.19x faster |
| function_call_nested | 104.19 ms | 87.40 ms | 1.19x faster |
- Direct typed return-to-local materially improves the int-return assignment workloads while preserving the loop and binary regression gates.
function_call_int,function_call_loop_return, andfunction_call_nestedall improve clearly, matching the primary v1.6 target.- The stretch target for
function_callbelow 90 ms was not reached in this median run; the remaining cost is still frame setup, typed argument transfer, and executing small function bodies.
Version: v1.7.0
Build: release
Date: 2026-05-11
Optimizations: Added a separate VM i64 operand stack and typed call-chain opcodes (CALL_FN_I64_TO_I64_STACK, RETURN_I64_TO_I64_STACK) so compiler-proven int function bodies and typed call-chain expressions avoid boxed Value::Int temporaries. Direct assignment from int-return functions still uses CALL_FN_I64_TO_LOCAL. This pass also added fused local-int compare-and-jump opcodes for the existing loop condition fast path so loop regression gates stay below the v1.6 baseline.
Baseline note: VM v1.7.0 was measured as local release-build medians from five runs on the feature branch. Most rows compare against the recorded VM v1.6.0 medians. function_call_chain and function_call_many_args were not recorded in the v1.6.0 table, so their baseline is the same-session release-v1.6.1 executable median from five runs. Timings remain noisy on this machine; this table is a directional performance record and regression gate.
| Benchmark | VM baseline median | VM v1.7.0 median | Change |
|---|---|---|---|
| loop_sum | 21.03 ms | 17.42 ms | 1.21x faster |
| loop_sum_large | 41.09 ms | 34.45 ms | 1.19x faster |
| nested_int_loop | 20.88 ms | 15.77 ms | 1.32x faster |
| binary_read_u32 | 67.01 ms | 66.13 ms | 1.01x faster |
| buffer_replace | 8.88 ms | 8.14 ms | 1.09x faster |
| patch_workflow | 23.46 ms | 21.99 ms | 1.07x faster |
| function_call | 106.17 ms | 76.11 ms | 1.39x faster |
| function_call_int | 123.07 ms | 97.94 ms | 1.26x faster |
| function_call_loop_return | 126.05 ms | 84.74 ms | 1.49x faster |
| function_call_nested | 87.40 ms | 64.64 ms | 1.35x faster |
| function_call_chain | 169.01 ms | 97.71 ms | 1.73x faster |
| function_call_many_args | 149.95 ms | 74.45 ms | 2.01x faster |
- Typed i64 call-chain execution materially improves the function-call-heavy workloads, especially chained and many-argument int-return calls.
function_call,function_call_int, andfunction_call_loop_returnall clear the v1.7 primary targets in this median run.- The loop and binary workloads stay inside the no-regression gate and improve after replacing typed local compare plus boxed bool branching with fused compare-and-jump bytecode.
Python: 3.12.9 Build: release Date: 2026-05-11
Baseline note: bench --compare-python was run five times on the v1.7.0 branch and the medians below are computed per benchmark. The safe claim from this run is: DByte v1.7.0 outperforms Python on measured low-level binary parsing, buffer patching, and typed integer loop workloads, plus the optimized many-argument typed call workload. It is not correct yet to claim that DByte is broadly faster than Python.
| Benchmark | Python median | DByte VM median | Python / DByte VM |
|---|---|---|---|
| binary_read_u32 | 110.87 ms | 65.92 ms | 1.68x |
| buffer_replace | 15.23 ms | 8.07 ms | 1.89x |
| patch_workflow | 32.56 ms | 21.67 ms | 1.50x |
| loop_sum | 33.44 ms | 15.29 ms | 2.19x |
| loop_sum_large | 68.64 ms | 31.94 ms | 2.15x |
| nested_int_loop | 31.43 ms | 15.56 ms | 2.02x |
| function_call_loop_return | 56.07 ms | 90.71 ms | 0.62x |
| function_call_many_args | 75.02 ms | 71.43 ms | 1.05x |
| function_call | 57.03 ms | 78.53 ms | 0.73x |
| function_call_int | 49.96 ms | 102.93 ms | 0.49x |
| function_call_nested | 32.15 ms | 61.37 ms | 0.52x |
| function_call_chain | 74.05 ms | 97.27 ms | 0.76x |
| bytes_find | 1.07 ms | 11.27 ms | 0.09x |
- Must-win binary, buffer, patching, and typed-loop workloads beat Python in the five-run median.
function_call_many_argsbeats Python slightly after the typed i64 operand-stack work.function_call_loop_returndoes not beat Python yet, so the broader "faster than Python on DByte's target workloads" wording is not supported by this run.bytes_findstill loses heavily to Python's native search path and remains the clearest blocker for broader benchmark-suite claims.
Version: v1.8.0
Build: release
Date: 2026-05-11
Optimizations: Replaced the naive O(n*m) sliding-window windows().position() byte search in both the VM intrinsic Op::BufferFind path and the NativeFn::BufferFind slow-path with SIMD-accelerated memchr crate. Single-byte patterns use memchr::memchr (x86 PCMPESTRI/PCMPISTRI path), multi-byte patterns use memchr::memmem::find (two-way algorithm with SIMD vectorization). The tree interpreter was patched in the same commit for full tree/VM parity.
| Benchmark | VM v1.7.1 median | VM v1.8.0 median | Change |
|---|---|---|---|
| bytes_find | 11.27 ms | 0.38 ms | 29.7x faster |
| bytes_find_single | (new) | 0.17 ms | (new) |
| buffer_replace | 8.07 ms | 7.94 ms | 1.02x (no regression) |
| binary_read_u32 | 65.92 ms | 73.18 ms | within noise |
| patch_workflow | 21.67 ms | 27.46 ms | within noise |
| loop_sum | 15.29 ms | 17.53 ms | within noise |
| Benchmark | Python median | DByte VM median | DByte / Python |
|---|---|---|---|
| bytes_find | 1.51 ms | 0.38 ms | 3.94x faster |
| bytes_find_single | 0.53 ms | 0.18 ms | 2.96x faster |
| binary_read_u32 | 108.45 ms | 69.44 ms | 1.56x faster |
| buffer_replace | 16.67 ms | 8.80 ms | 1.89x faster |
| patch_workflow | 37.95 ms | 22.03 ms | 1.72x faster |
| loop_sum | 36.57 ms | 18.19 ms | 2.01x faster |
| int_compare_loop | 66.61 ms | 38.11 ms | 1.75x faster |
bytes_findis now 29.7x faster vs v1.7.1 and beats Python by 3.94x in the measured workload.bytes_find_single(new benchmark, 1-byte pattern) beats Python by 2.96x.- All existing no-regression gate benchmarks remain within noise tolerance.
- This closes the
bytes_findblocker. DByte v1.8.0 now beats Python on all measured binary, buffer, patching, and typed-integer-loop workloads.
Version: v1.9.0 Build: release Date: 2026-05-11 Optimizations: Implemented bytecode-level function inlining in the compiler for simple non-recursive functions. Re-mapped jump targets and local offsets during compilation, removing the Op::CallFn overhead and frame dispatch entirely for tight loop calls. Also optimized discarded calls by pushing Op::PopI64Stack natively.
| Benchmark | Python | DByte VM | Ratio |
|---|---|---|---|
| binary_read_u32 | 159.52 ms | 66.14 ms | 2.41x faster |
| buffer_replace | 14.68 ms | 8.90 ms | 1.65x faster |
| bytes_find | 1.14 ms | 0.46 ms | 2.46x faster |
| bytes_find_single | 0.34 ms | 0.20 ms | 1.72x faster |
| function_call | 53.17 ms | 39.98 ms | 1.33x faster |
| function_call_chain | 81.58 ms | 47.23 ms | 1.73x faster |
| function_call_int | 55.08 ms | 55.10 ms | 1.00x |
| function_call_loop_return | 60.84 ms | 42.40 ms | 1.43x faster |
| function_call_many_args | 78.41 ms | 65.66 ms | 1.19x faster |
| function_call_nested | 33.38 ms | 29.54 ms | 1.13x faster |
| int_compare_loop | 60.45 ms | 39.71 ms | 1.52x faster |
| loop_sum | 38.68 ms | 15.16 ms | 2.55x faster |
| loop_sum_large | 71.42 ms | 31.06 ms | 2.30x faster |
| nested_int_loop | 33.41 ms | 18.28 ms | 1.83x faster |
| patch_workflow | 36.06 ms | 21.94 ms | 1.64x faster |
- DByte v1.9.0 is faster than Python on nearly all measured benchmarks, including binary parsing, byte search, buffer patching, typed integer loops, and most function-call workloads.
- Function inlining significantly reduced the overhead of small function calls, though some complex call chains (
function_call_int) are still hitting the limits of the current inlining guards. - Small function abstraction is now approaching zero-cost, but further refinement of the I64 return path and argument transfer is planned for v1.9.1 to definitively beat Python on every workload.
Version: v1.9.1 Build: release Date: 2026-05-11 Optimizations: Implemented direct argument remapping in the inliner. By analyzing parameter usage (read-only checks), the compiler now substitutes parameter loads with direct caller local loads or constants, eliminating the stack-to-local shuffle. This achieves true zero-cost abstraction for small helper functions.
| Benchmark | Python | DByte VM | Ratio |
|---|---|---|---|
| binary_read_u32 | 114.32 ms | 63.99 ms | 1.79x faster |
| buffer_replace | 13.91 ms | 7.86 ms | 1.77x faster |
| bytes_find | 1.12 ms | 0.36 ms | 3.07x faster |
| bytes_find_single | 0.31 ms | 0.22 ms | 1.38x faster |
| function_call | 51.47 ms | 30.36 ms | 1.70x faster |
| function_call_chain | 83.77 ms | 28.98 ms | 2.89x faster |
| function_call_int | 57.83 ms | 30.03 ms | 1.93x faster |
| function_call_loop_return | 59.23 ms | 34.81 ms | 1.70x faster |
| function_call_many_args | 81.65 ms | 34.71 ms | 2.35x faster |
| function_call_nested | 32.81 ms | 18.21 ms | 1.80x faster |
| int_compare_loop | 62.55 ms | 38.82 ms | 1.61x faster |
| loop_sum | 35.03 ms | 17.65 ms | 1.98x faster |
| loop_sum_large | 93.97 ms | 37.42 ms | 2.51x faster |
| nested_int_loop | 39.24 ms | 15.79 ms | 2.49x faster |
| patch_workflow | 36.51 ms | 24.96 ms | 1.46x faster |
- DByte v1.9.1 beats Python across the full measured benchmark suite on this Windows release-build test machine.
- 'Zero-Cost Inlining' has successfully eliminated the remaining measured bottleneck in function call overhead.
- Simple helper functions (like
add,get,check) now incur literally zero runtime overhead when inlined, producing optimal instruction sequences identical to hand-written inline logic.
Version: v2.1.0 Build: release Date: 2026-05-11
v2.1.0 is not a performance release. It adds the personal runtime layer
(dbyte repl, dbyte shell, and current-directory .dbyterc loading for
interactive commands only). The safe performance claim remains limited to the
measured benchmark suite and machine described above.
Version: v2.1.1 Build: release Date: 2026-05-11
v2.1.1 is not a performance release. It hardens the interactive runtime added in
v2.1.0 with additional REPL, shell, and .dbyterc regression coverage. The
benchmark claim remains unchanged.
Version: v2.2.0 Build: release Date: 2026-05-11
v2.2.0 is not a performance release. It adds the embeddable tree-runtime crate for host applications and keeps benchmark claims limited to the measured suite.
Version: v2.2.1 Build: release Date: 2026-05-11
v2.2.1 is not a performance release. It hardens the embeddable runtime API,
including capture isolation, .dbyterc behavior, cwd handling, and rollback
coverage.