You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Hot-loop JS performance: JSON×10k is 14.8× slower than Bun in a warm isolate #37
Process startup and memory are now consistently strong (v0.10.5 beats Node and Deno on all 22 validated apps, Bun on 17/22, 10.9 MiB RSS vs Bun 16.7 MiB). The remaining performance gap is steady-state JavaScript execution inside a warm isolate:
Workload (median of 90 calls, warm engine)
Slice 0.10.5
Bun
Node
Deno
JSON.parse+stringify ×10,000
55.7 ms
3.8 ms
5.5 ms
4.0 ms
Numeric loop ×10,000
3.02 ms
0.40 ms
1.83 ms
1.66 ms
That is 14.8× slower than Bun on JSON (down from 30.9× in 0.9.9 — the monomorphic inline caches in the vendored Boa clearly helped) and 7.6× on numeric code that numeric_vm does not catch.
Why it matters
Slice's target workloads (per-request handlers, agent tool calls, tenant automations) are short — but "short" still includes parsing a 200 KB JSON body, running a template engine, or validating a schema with zod. At 15× those become the dominant cost and erase the startup advantage after a handful of requests.
Proposal — in order of cost/benefit
Polymorphic inline caches (2–4 entry) for property get/set and method calls; the current IC is monomorphic (get_fast).
Shape/hidden-class transitions with a transition tree so object literals built in a loop share shapes; most JSON-heavy code benefits immediately.
Fast paths in JSON.parse/JSON.stringify operating on the shape table directly (the streaming JsonSeed parser is a start; stringify still walks generic property enumeration).
Baseline JIT for hot CodeBlocks via cranelift — a 1:1 bytecode→machine-code translation without speculation keeps the attack surface small, keeps fuel metering exact (emit a counter decrement per basic block), and historically gives 2–5× over a bytecode interpreter.
Publish a benchmarks/hot-loop/ micro-suite in CI so each of the above has a visible before/after.
Alternatively, document the trade-off explicitly: Slice is an interpreter by design (determinism, metering, memory safety) and hot-loop performance will stay in the interpreter class.
Added a direct Vec +
yu_js + shape property-table (Shape::with_property_keys) fast-path for JSON.stringify and a zero-copy Latin1 borrow path for JSON.parse in �endor/boa_engine/src/builtins/json/mod.rs.
Measured speedup: JSON.stringify x 10,000 improved 12.48x (60.0 ms -> 4.81 ms), and JSON.parse(JSON.stringify(obj)) x 10,000 improved 2.92x (94.0 ms -> 32.16 ms).
Activity
siktec-lab commentedon Nov 9, 2026
Addressed in #41 (�0.10.6).
yu_js + shape property-table (Shape::with_property_keys) fast-path for JSON.stringify and a zero-copy Latin1 borrow path for JSON.parse in �endor/boa_engine/src/builtins/json/mod.rs.