Skip to content

perf(bytecode): specialize proven numeric recursion#994

Merged
frostney merged 3 commits into
mainfrom
codex/numeric-superinstructions
Jul 21, 2026
Merged

perf(bytecode): specialize proven numeric recursion#994
frostney merged 3 commits into
mainfrom
codex/numeric-superinstructions

Conversation

@frostney

@frostney frostney commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a closed-world Number proof for simple const-bound local arrows. Mixed arguments, wrong arity, escapes, optional/spread calls, unsupported syntax, and non-simple parameters cancel the proof.
  • Add OP_SUB_NUM_IMM and OP_JUMP_IF_NUM_NOT_LTE_IMM so provably numeric subtraction and conditional <= avoid generic arithmetic/comparison dispatches.
  • Add OP_CALL_SELF_NUM for proven non-tail self-calls with one to three scalar arguments. It uses compact recursive register frames while preserving stack limits, traces, profiling, coverage, timeouts, instruction limits, and GC safety. Generic entry and proper tail calls remain unchanged. The GBC format is now v75.
  • Record the boundary and measurements in ADR 0101. Acceptance is based on the retained untyped Fibonacci probe and pinned upstream AWFY Sieve at 74306fec151070fd07157cefeacf19e7e0bcdc89, not the aggregate benchmark.

Testing

  • Verified no regressions and confirmed the new feature or bugfix in end-to-end JavaScript/TypeScript tests
  • Updated documentation
  • Optional: Verified no regressions and confirmed the new feature or bugfix in native Pascal tests (if AST, scope, evaluator, or value types changed)
  • Optional: Verified no benchmark regressions or confirmed benchmark coverage for the change

Conformance and repository gates:

  • Interpreter: 1,442 files, 11,519 tests, 25,742 assertions; 100% pass.
  • Bytecode: 1,442 files, 11,519 tests, 25,742 assertions; 100% pass after the final GC-safety change.
  • Clean native test build passes; compiler tests pass 46/46 and VM tests pass 13/13.
  • ./format.pas --check, Markdown lint, documentation links/symbols/duplication/length, truncation guards, and git diff --check pass.

Deterministic retained Fibonacci profile, one inner iteration:

Revision Total dispatches Generic self-load + call dispatches Specialized self-calls
origin/main 262,915 43,785 0
numeric-immediate predecessor 197,243 43,785 0
candidate 164,408 5 outer calls 21,890

Matched production wall time, 25 inner iterations and nine interleaved repetitions:

Comparison Baseline median Candidate median Reduction
origin/main 241.359 ms 72.211 ms 70.1%
numeric-immediate predecessor 228.870 ms 72.722 ms 68.2%

The independent predecessor comparison was stable at 0.83% baseline CV and 1.02% candidate CV. The main comparison contained one first-candidate cold outlier; its median remained 70.1% faster and the other candidate samples clustered at 71.7-73.0 ms. Every timed sample verified the expected checksum.

Pinned non-synthetic AWFY Sieve guard, 10 inner iterations and nine interleaved repetitions:

Comparison Baseline median Candidate median Change
numeric-immediate predecessor 95.032 ms 95.453 ms 0.44% slower
origin/main 97.003 ms 95.254 ms 1.8% faster

The predecessor comparison measured 0.64% baseline CV and 1.00% candidate CV, placing the 0.44% difference within matched noise.

@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Preview Jul 21, 2026 4:01am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 056ac08b-8879-4562-afbf-aa6f94e5e254

📥 Commits

Reviewing files that changed from the base of the PR and between 31c2977 and 5c5d3f8.

📒 Files selected for processing (16)
  • docs/adr/0101-closed-numeric-scalar-self-call-frames.md
  • docs/adr/README.md
  • docs/bytecode-vm.md
  • source/units/Goccia.Bytecode.Chunk.pas
  • source/units/Goccia.Bytecode.OpCodeNames.pas
  • source/units/Goccia.Bytecode.pas
  • source/units/Goccia.Compiler.Context.pas
  • source/units/Goccia.Compiler.Expressions.pas
  • source/units/Goccia.Compiler.NumericProof.pas
  • source/units/Goccia.Compiler.Scope.pas
  • source/units/Goccia.Compiler.Test.pas
  • source/units/Goccia.Compiler.pas
  • source/units/Goccia.VM.Test.pas
  • source/units/Goccia.VM.pas
  • tests/language/functions/recursive-functions.js
  • tests/language/functions/stack-depth-limit.js

📝 Walkthrough

Walkthrough

This PR adds proof-backed closed numeric self-call compilation and VM execution. It introduces three opcodes, compact numeric frames with unwind support, immediate numeric operations, compiler proof discovery, bytecode version 75, documentation, and compiler, VM, and language tests.

Changes

Closed numeric self-call specialization

Layer / File(s) Summary
Proof contracts and compiler plumbing
source/units/Goccia.Bytecode*.pas, source/units/Goccia.Compiler.Context.pas, source/units/Goccia.Compiler.NumericProof.pas, source/units/Goccia.Compiler.Scope.pas, source/units/Goccia.Compiler.pas
Adds numeric proof types, proof discovery, compiler state propagation, local proof flags, new opcodes, and bytecode format version 75.
Numeric proof lowering
source/units/Goccia.Compiler.Expressions.pas, docs/bytecode-vm.md
Emits OP_CALL_SELF_NUM, OP_SUB_NUM_IMM, and OP_JUMP_IF_NUM_NOT_LTE_IMM for eligible proven expressions and calls.
Numeric frame execution and unwinding
source/units/Goccia.VM.pas
Adds compact numeric frame storage, specialized opcode execution, return restoration, profiling state handling, and exception unwinding.
Round-trip, runtime, and language validation
source/units/Goccia.Compiler.Test.pas, source/units/Goccia.VM.Test.pas, tests/language/functions/*, docs/adr/*
Adds serialization, opcode, arithmetic, recursion, arity, proof-rejection, stack-limit, VM semantics, and ADR coverage.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: performance, documentation, internal

Sequence Diagram(s)

sequenceDiagram
  participant Source
  participant TGocciaCompiler
  participant TGocciaVM
  participant Tests
  Source->>TGocciaCompiler: compile closed numeric recursive function
  TGocciaCompiler->>TGocciaVM: emit OP_CALL_SELF_NUM and numeric immediate opcodes
  TGocciaVM->>TGocciaVM: push, execute, return, or unwind numeric frame
  TGocciaVM-->>Tests: produce numeric result or stack-limit error
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: specializing proven numeric recursion.
Description check ✅ Passed The description matches the template with Summary and Testing sections and includes the required implementation and validation details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Web Tooling Benchmark

Workload Status Goccia
acorn pass 0.03 runs/s
babel pass 0.01 runs/s
babel-minify pass 0.09 runs/s
babylon pass 0.04 runs/s
buble pass 0.09 runs/s
chai pass 0.13 runs/s
coffeescript pass 0.01 runs/s
espree pass 0.03 runs/s
esprima pass 0.04 runs/s
jshint pass 0.01 runs/s
lebab pass 0.09 runs/s
postcss pass 0.02 runs/s
prepack pass 0.10 runs/s
prettier pass 0.07 runs/s
source-map pass 0.03 runs/s
terser pass 219 runs/s
typescript pass 0.10 runs/s
uglify-js pass 127 runs/s

18 pinned Web Tooling workloads; 18 workloads produced at least one Goccia sample. Raw results from 1 sample per workload; full stdout/stderr for failures and min/max/CV stay in the web-tooling-report artifact. This lane is Goccia-only by design.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Suite Timing

Test Runner (interpreted: 11,519 passed; bytecode: 11,519 passed)
Metric Interpreted Bytecode
Total 11519 11519
Passed 11519 ✅ 11519 ✅
Workers 4 4
Test Duration 18.66s 17.03s
Lex (cumulative) 1.82s 1.79s
Parse (cumulative) 979.3ms 957.1ms
Compile (cumulative) 1.12s
Execute (cumulative) 799.5ms 15.75s
Engine Total (cumulative) 3.60s 19.62s
Lex (avg/worker) 455.6ms 448.7ms
Parse (avg/worker) 244.8ms 239.3ms
Compile (avg/worker) 279.3ms
Execute (avg/worker) 199.9ms 3.94s
Engine Total (avg/worker) 900.3ms 4.90s

Memory

GC rows aggregate the main thread plus all worker thread-local GCs. Test runner worker shutdown frees thread-local heaps in bulk; that shutdown reclamation is not counted as GC collections or collected objects.

Metric Interpreted Bytecode
GC Live 64.86 MiB 61.90 MiB
GC Peak Live 207.58 MiB 180.45 MiB
GC Allocated During Run 521.81 MiB 454.40 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 226 226
GC Collected Objects 4,392,731 3,850,387
Heap Start Allocated 326.3 KiB 326.3 KiB
Heap End Allocated 2.89 MiB 2.90 MiB
Heap Delta Allocated 2.58 MiB 2.58 MiB
Heap Delta Free 2.24 MiB 2.24 MiB
Benchmarks (interpreted: 439; bytecode: 439)
Metric Interpreted Bytecode
Total 439 439
Workers 4 4
Duration 3.10min 3.05min

Memory

GC rows aggregate the main thread plus all worker thread-local GCs. Benchmark runner performs explicit between-file collections, so collection and collected-object counts can be much higher than the test runner.

Metric Interpreted Bytecode
GC Live 808 B 808 B
GC Peak Live 140.22 MiB 85.49 MiB
GC Allocated During Run 15.64 GiB 13.23 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 5,994 6,462
GC Collected Objects 229,429,960 287,254,877
Heap Start Allocated 1.36 MiB 1.36 MiB
Heap End Allocated 1.37 MiB 1.37 MiB
Heap Delta Allocated 3.2 KiB 3.2 KiB
Boot
Metric Interpreted Bytecode
Boot (median) 7.2ms 7.4ms
Boot (min) 7.0ms 7.2ms

Empty-script (0;) end-to-end process wall-clock for GocciaScriptLoader, min and median over 60 runs after 10 warmups. Includes a fixed process / dynamic-loader floor that does not shrink, so it understates the engine-boot speedup; treat as practical boot time, not pure engine work.

Measured on ubuntu-latest x64.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

439 benchmarks · PR vs same-runner main build

Interpreted: 🟢 41 improved · 🔴 25 regressed · 373 unchanged · avg +1.5%
Bytecode: 🟢 38 improved · 🔴 29 regressed · 372 unchanged · avg +3.6%

Typical per-run noise (median variance): interpreted ±2.0%, bytecode ±2.7%. Deltas within noise overlap and read as unchanged.

arraybuffer.js — Interp: 14 unch. · avg +0.1% · Bytecode: 🟢 3, 11 unch. · avg +0.4%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
create ArrayBuffer(0) 95,371 ops/sec [91,359..109,089] → 97,032 ops/sec [77,041..126,270] ~ overlap (+1.7%) 209,047 ops/sec [208,417..213,609] → 210,733 ops/sec [209,288..213,403] ~ overlap (+0.8%)
create ArrayBuffer(64) 93,322 ops/sec [92,154..96,115] → 94,531 ops/sec [93,449..110,710] ~ overlap (+1.3%) 207,726 ops/sec [201,884..259,918] → 201,450 ops/sec [199,901..203,050] ~ overlap (-3.0%)
create ArrayBuffer(1024) 84,575 ops/sec [63,965..89,135] → 86,975 ops/sec [84,660..96,791] ~ overlap (+2.8%) 178,219 ops/sec [173,855..180,920] → 177,235 ops/sec [173,347..190,022] ~ overlap (-0.6%)
create ArrayBuffer(8192) 59,098 ops/sec [58,521..61,326] → 59,046 ops/sec [58,802..59,424] ~ overlap (-0.1%) 97,019 ops/sec [75,602..100,335] → 94,582 ops/sec [89,725..96,005] ~ overlap (-2.5%)
slice full buffer (64 bytes) 73,428 ops/sec [71,523..75,006] → 72,615 ops/sec [70,064..73,293] ~ overlap (-1.1%) 129,377 ops/sec [124,295..134,922] → 129,830 ops/sec [129,409..130,723] ~ overlap (+0.3%)
slice half buffer (512 of 1024 bytes) 69,278 ops/sec [67,030..69,431] → 66,416 ops/sec [65,331..72,015] ~ overlap (-4.1%) 122,883 ops/sec [122,590..123,118] → 123,581 ops/sec [122,712..125,359] ~ overlap (+0.6%)
slice with negative indices 64,210 ops/sec [62,191..72,040] → 62,348 ops/sec [62,189..63,946] ~ overlap (-2.9%) 123,088 ops/sec [121,913..125,306] → 128,570 ops/sec [126,670..129,091] 🟢 +4.5%
slice empty range 69,781 ops/sec [68,709..71,438] → 69,950 ops/sec [68,548..70,046] ~ overlap (+0.2%) 125,396 ops/sec [123,366..126,207] → 130,644 ops/sec [129,788..131,093] 🟢 +4.2%
byteLength access 182,539 ops/sec [174,638..195,845] → 181,332 ops/sec [180,263..198,583] ~ overlap (-0.7%) 331,932 ops/sec [328,181..342,128] → 348,583 ops/sec [345,769..360,131] 🟢 +5.0%
Symbol.toStringTag access 178,913 ops/sec [175,252..180,258] → 182,849 ops/sec [176,533..208,106] ~ overlap (+2.2%) 312,079 ops/sec [293,208..324,744] → 315,176 ops/sec [313,909..315,736] ~ overlap (+1.0%)
ArrayBuffer.isView 136,418 ops/sec [135,108..137,397] → 136,645 ops/sec [134,076..146,086] ~ overlap (+0.2%) 283,045 ops/sec [279,522..335,603] → 283,758 ops/sec [277,923..318,137] ~ overlap (+0.3%)
clone ArrayBuffer(64) 106,658 ops/sec [105,583..119,041] → 109,070 ops/sec [107,431..129,730] ~ overlap (+2.3%) 213,920 ops/sec [208,186..259,247] → 208,554 ops/sec [207,796..213,696] ~ overlap (-2.5%)
clone ArrayBuffer(1024) 96,179 ops/sec [95,392..98,020] → 96,657 ops/sec [95,119..98,779] ~ overlap (+0.5%) 180,911 ops/sec [179,624..182,442] → 179,687 ops/sec [175,903..182,917] ~ overlap (-0.7%)
clone ArrayBuffer inside object 70,761 ops/sec [69,249..76,364] → 69,793 ops/sec [66,825..70,465] ~ overlap (-1.4%) 125,600 ops/sec [125,071..125,693] → 122,600 ops/sec [119,890..144,910] ~ overlap (-2.4%)
arrays.js — Interp: 🟢 1, 18 unch. · avg +0.8% · Bytecode: 🔴 2, 17 unch. · avg -1.4%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
Array.from length 100 2,223 ops/sec [2,137..2,263] → 2,278 ops/sec [1,925..2,396] ~ overlap (+2.4%) 2,860 ops/sec [2,653..3,047] → 2,917 ops/sec [2,362..3,453] ~ overlap (+2.0%)
Array.from 10 elements 14,350 ops/sec [13,665..18,383] → 14,266 ops/sec [13,805..16,337] ~ overlap (-0.6%) 21,956 ops/sec [21,363..26,031] → 22,417 ops/sec [20,292..24,690] ~ overlap (+2.1%)
Array.of 10 elements 44,825 ops/sec [44,125..46,019] → 45,699 ops/sec [44,468..45,963] ~ overlap (+1.9%) 84,143 ops/sec [82,949..84,771] → 81,648 ops/sec [81,031..82,682] 🔴 -3.0%
spread into new array 71,374 ops/sec [68,486..108,185] → 69,160 ops/sec [68,189..79,703] ~ overlap (-3.1%) 86,707 ops/sec [61,114..93,329] → 60,128 ops/sec [58,579..60,808] 🔴 -30.7%
map over 50 elements 3,852 ops/sec [3,814..3,884] → 3,822 ops/sec [3,776..4,059] ~ overlap (-0.8%) 6,154 ops/sec [6,053..6,181] → 6,103 ops/sec [5,945..6,143] ~ overlap (-0.8%)
filter over 50 elements 4,033 ops/sec [4,009..4,063] → 4,074 ops/sec [4,053..4,124] ~ overlap (+1.0%) 6,438 ops/sec [6,144..6,759] → 6,727 ops/sec [6,622..7,461] ~ overlap (+4.5%)
reduce sum 50 elements 4,625 ops/sec [4,551..4,703] → 4,729 ops/sec [4,693..5,270] ~ overlap (+2.2%) 7,055 ops/sec [6,912..7,144] → 7,191 ops/sec [7,096..7,723] ~ overlap (+1.9%)
forEach over 50 elements 3,208 ops/sec [3,185..3,245] → 3,339 ops/sec [3,279..3,894] 🟢 +4.1% 7,758 ops/sec [7,554..8,095] → 7,912 ops/sec [7,711..8,694] ~ overlap (+2.0%)
find in 50 elements 6,491 ops/sec [6,441..6,560] → 6,481 ops/sec [6,231..7,313] ~ overlap (-0.1%) 9,527 ops/sec [9,398..9,946] → 9,622 ops/sec [9,331..9,892] ~ overlap (+1.0%)
sort 20 elements 3,536 ops/sec [3,487..3,749] → 3,515 ops/sec [3,481..3,531] ~ overlap (-0.6%) 5,621 ops/sec [5,554..5,651] → 5,512 ops/sec [5,477..5,614] ~ overlap (-1.9%)
flat nested array 26,732 ops/sec [26,474..27,148] → 26,814 ops/sec [26,393..27,324] ~ overlap (+0.3%) 46,112 ops/sec [45,363..46,657] → 45,797 ops/sec [43,145..47,628] ~ overlap (-0.7%)
flatMap 16,363 ops/sec [15,991..16,522] → 16,195 ops/sec [16,042..16,293] ~ overlap (-1.0%) 25,914 ops/sec [25,821..26,088] → 25,831 ops/sec [25,417..27,745] ~ overlap (-0.3%)
map inside map (5x5) 4,825 ops/sec [4,773..4,828] → 4,778 ops/sec [4,709..4,796] ~ overlap (-1.0%) 7,444 ops/sec [7,369..7,485] → 7,682 ops/sec [7,192..8,303] ~ overlap (+3.2%)
filter inside map (5x10) 3,134 ops/sec [3,066..3,258] → 3,098 ops/sec [3,026..3,169] ~ overlap (-1.1%) 5,167 ops/sec [4,959..5,421] → 4,982 ops/sec [4,911..5,663] ~ overlap (-3.6%)
reduce inside map (5x10) 3,740 ops/sec [3,602..4,497] → 3,814 ops/sec [3,683..3,868] ~ overlap (+2.0%) 5,749 ops/sec [5,672..6,653] → 5,850 ops/sec [5,808..6,370] ~ overlap (+1.8%)
forEach inside forEach (5x10) 2,881 ops/sec [2,733..3,146] → 3,029 ops/sec [2,777..3,651] ~ overlap (+5.1%) 6,359 ops/sec [6,177..6,599] → 6,255 ops/sec [6,218..6,569] ~ overlap (-1.6%)
find inside some (10x10) 2,800 ops/sec [2,769..2,898] → 2,881 ops/sec [2,819..2,938] ~ overlap (+2.9%) 4,490 ops/sec [4,269..4,545] → 4,388 ops/sec [4,265..4,430] ~ overlap (-2.3%)
map+filter chain nested (5x20) 932 ops/sec [919..946] → 933 ops/sec [921..953] ~ overlap (+0.0%) 1,457 ops/sec [1,444..1,554] → 1,473 ops/sec [1,337..1,566] ~ overlap (+1.1%)
reduce flatten (10x5) 6,571 ops/sec [6,526..6,831] → 6,668 ops/sec [6,443..7,997] ~ overlap (+1.5%) 4,224 ops/sec [4,072..4,390] → 4,140 ops/sec [4,106..4,203] ~ overlap (-2.0%)
async-await.js — Interp: 🟢 1, 5 unch. · avg +1.8% · Bytecode: 🟢 1, 5 unch. · avg +1.3%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
single await 19,757 ops/sec [17,463..20,260] → 20,460 ops/sec [20,004..20,539] ~ overlap (+3.6%) 36,002 ops/sec [32,665..40,051] → 37,149 ops/sec [32,668..40,087] ~ overlap (+3.2%)
multiple awaits 8,543 ops/sec [8,086..9,689] → 8,277 ops/sec [8,234..8,330] ~ overlap (-3.1%) 13,109 ops/sec [12,729..13,396] → 12,799 ops/sec [12,479..13,029] ~ overlap (-2.4%)
await non-Promise value 28,935 ops/sec [27,346..35,964] → 28,635 ops/sec [28,559..29,452] ~ overlap (-1.0%) 52,563 ops/sec [50,398..56,185] → 52,110 ops/sec [51,037..54,730] ~ overlap (-0.9%)
await with try/catch 18,098 ops/sec [17,611..20,475] → 19,065 ops/sec [18,057..20,363] ~ overlap (+5.3%) 36,217 ops/sec [31,643..36,761] → 36,097 ops/sec [36,055..36,297] ~ overlap (-0.3%)
await Promise.all 4,969 ops/sec [4,728..5,192] → 4,767 ops/sec [4,329..4,958] ~ overlap (-4.1%) 6,896 ops/sec [6,729..6,965] → 7,600 ops/sec [7,575..7,617] 🟢 +10.2%
nested async function call 10,770 ops/sec [10,560..11,738] → 11,889 ops/sec [11,771..12,907] 🟢 +10.4% 21,410 ops/sec [20,907..21,639] → 20,966 ops/sec [20,841..22,255] ~ overlap (-2.1%)
async-generators.js — Interp: 2 unch. · avg -0.9% · Bytecode: 2 unch. · avg -2.9%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
for-await-of over async generator 1,370 ops/sec [1,183..1,479] → 1,312 ops/sec [1,230..1,354] ~ overlap (-4.3%) 864 ops/sec [744..932] → 855 ops/sec [787..1,013] ~ overlap (-1.1%)
async generator with await in body 5,168 ops/sec [4,711..5,683] → 5,300 ops/sec [5,179..6,719] ~ overlap (+2.6%) 6,797 ops/sec [6,708..8,185] → 6,475 ops/sec [6,427..6,927] ~ overlap (-4.7%)
atomics.js — Interp: 🟢 1, 5 unch. · avg +3.4% · Bytecode: 🟢 2, 4 unch. · avg +2.5%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
load and store Int32Array 65,753 ops/sec [65,162..66,356] → 67,224 ops/sec [66,551..69,275] 🟢 +2.2% 153,030 ops/sec [150,576..154,681] → 155,316 ops/sec [153,674..167,827] ~ overlap (+1.5%)
read-modify-write Int32Array 47,213 ops/sec [46,806..49,649] → 49,962 ops/sec [49,293..55,189] ~ overlap (+5.8%) 102,862 ops/sec [101,396..104,496] → 107,847 ops/sec [107,610..108,236] 🟢 +4.8%
compareExchange hit and miss 44,940 ops/sec [43,663..46,886] → 47,208 ops/sec [46,724..48,392] ~ overlap (+5.0%) 96,097 ops/sec [94,361..98,034] → 101,205 ops/sec [100,603..101,677] 🟢 +5.3%
wait with zero timeout 112,601 ops/sec [111,620..114,236] → 113,866 ops/sec [112,702..114,252] ~ overlap (+1.1%) 255,527 ops/sec [249,487..259,301] → 248,603 ops/sec [246,622..252,759] ~ overlap (-2.7%)
waitAsync synchronous not-equal 81,567 ops/sec [80,440..83,600] → 86,713 ops/sec [64,197..97,246] ~ overlap (+6.3%) 159,015 ops/sec [157,314..181,595] → 166,265 ops/sec [159,954..187,385] ~ overlap (+4.6%)
notify with no waiters 113,232 ops/sec [111,424..120,623] → 113,391 ops/sec [111,257..138,211] ~ overlap (+0.1%) 249,788 ops/sec [243,238..261,310] → 253,997 ops/sec [253,681..254,440] ~ overlap (+1.7%)
base64.js — Interp: 🔴 1, 9 unch. · avg -0.0% · Bytecode: 🔴 1, 9 unch. · avg +0.7%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
short ASCII (13 chars) 2,041 ops/sec [2,016..2,083] → 1,984 ops/sec [1,954..3,063] ~ overlap (-2.8%) 2,907 ops/sec [2,883..2,927] → 2,898 ops/sec [2,868..2,905] ~ overlap (-0.3%)
medium ASCII (450 chars) 74 ops/sec [72..77] → 77 ops/sec [73..89] ~ overlap (+4.4%) 103 ops/sec [102..105] → 102 ops/sec [101..103] ~ overlap (-0.8%)
Latin-1 characters 2,898 ops/sec [2,757..2,929] → 2,906 ops/sec [2,885..2,922] ~ overlap (+0.3%) 4,276 ops/sec [4,268..4,279] → 4,231 ops/sec [4,221..4,258] 🔴 -1.1%
short base64 (20 chars) 1,500 ops/sec [1,487..1,511] → 1,487 ops/sec [1,475..1,504] ~ overlap (-0.9%) 2,103 ops/sec [2,029..2,156] → 2,117 ops/sec [2,111..2,131] ~ overlap (+0.7%)
medium base64 (600 chars) 59 ops/sec [58..60] → 60 ops/sec [58..65] ~ overlap (+2.6%) 84 ops/sec [83..89] → 83 ops/sec [82..93] ~ overlap (-1.6%)
Latin-1 output 2,160 ops/sec [2,133..2,252] → 2,105 ops/sec [2,069..2,126] 🔴 -2.5% 3,074 ops/sec [2,977..3,125] → 3,038 ops/sec [3,020..3,050] ~ overlap (-1.2%)
forgiving (no padding) 3,168 ops/sec [3,076..3,224] → 3,121 ops/sec [3,082..3,291] ~ overlap (-1.5%) 4,530 ops/sec [4,502..4,566] → 4,554 ops/sec [4,527..4,624] ~ overlap (+0.5%)
with whitespace 1,459 ops/sec [1,414..1,475] → 1,472 ops/sec [1,427..1,567] ~ overlap (+0.9%) 2,131 ops/sec [2,080..2,277] → 2,110 ops/sec [2,049..2,218] ~ overlap (-1.0%)
atob(btoa(short)) 891 ops/sec [827..924] → 870 ops/sec [858..1,011] ~ overlap (-2.4%) 1,229 ops/sec [1,208..1,237] → 1,293 ops/sec [1,209..1,364] ~ overlap (+5.2%)
atob(btoa(medium)) 34 ops/sec [33..35] → 34 ops/sec [33..36] ~ overlap (+1.7%) 46 ops/sec [46..50] → 49 ops/sec [45..54] ~ overlap (+6.1%)
classes.js — Interp: 🟢 4, 🔴 1, 26 unch. · avg +0.8% · Bytecode: 🔴 1, 30 unch. · avg -0.9%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
simple class new 32,422 ops/sec [32,040..32,465] → 33,556 ops/sec [33,253..33,752] 🟢 +3.5% 70,575 ops/sec [68,850..71,366] → 71,035 ops/sec [70,357..71,415] ~ overlap (+0.7%)
class with defaults 25,641 ops/sec [25,483..28,074] → 26,234 ops/sec [26,175..26,398] ~ overlap (+2.3%) 51,302 ops/sec [50,890..58,583] → 49,456 ops/sec [48,562..53,402] ~ overlap (-3.6%)
50 instances via Array.from 1,174 ops/sec [1,167..1,182] → 1,182 ops/sec [1,174..1,230] ~ overlap (+0.6%) 1,952 ops/sec [1,939..2,009] → 1,949 ops/sec [1,929..1,960] ~ overlap (-0.2%)
instance method call 15,581 ops/sec [15,528..15,622] → 15,501 ops/sec [15,089..17,759] ~ overlap (-0.5%) 38,141 ops/sec [37,553..38,659] → 38,662 ops/sec [37,936..38,866] ~ overlap (+1.4%)
static method call 26,444 ops/sec [26,127..26,557] → 26,606 ops/sec [26,093..27,709] ~ overlap (+0.6%) 76,701 ops/sec [74,648..78,801] → 75,572 ops/sec [71,949..78,496] ~ overlap (-1.5%)
single-level inheritance 13,186 ops/sec [13,078..16,768] → 13,467 ops/sec [13,294..15,265] ~ overlap (+2.1%) 25,318 ops/sec [24,334..27,162] → 26,300 ops/sec [25,884..28,339] ~ overlap (+3.9%)
two-level inheritance 11,655 ops/sec [11,460..11,891] → 12,015 ops/sec [11,969..12,166] 🟢 +3.1% 19,826 ops/sec [19,573..21,148] → 19,416 ops/sec [19,140..20,322] ~ overlap (-2.1%)
private field access 16,542 ops/sec [16,289..16,569] → 16,753 ops/sec [16,671..16,857] 🟢 +1.3% 16,710 ops/sec [16,075..16,914] → 16,888 ops/sec [16,589..16,932] ~ overlap (+1.1%)
private methods 18,348 ops/sec [16,920..24,608] → 18,749 ops/sec [18,671..19,156] ~ overlap (+2.2%) 17,719 ops/sec [17,546..17,784] → 17,720 ops/sec [17,672..17,961] ~ overlap (+0.0%)
getter/setter access 17,720 ops/sec [17,376..19,139] → 18,076 ops/sec [17,810..18,868] ~ overlap (+2.0%) 38,749 ops/sec [38,299..40,219] → 38,917 ops/sec [38,271..39,210] ~ overlap (+0.4%)
class decorator (identity) 27,006 ops/sec [26,241..27,620] → 27,233 ops/sec [26,999..27,352] ~ overlap (+0.8%) 41,844 ops/sec [41,470..52,694] → 42,897 ops/sec [41,975..43,173] ~ overlap (+2.5%)
class decorator (wrapping) 14,875 ops/sec [14,801..17,246] → 15,579 ops/sec [15,241..18,961] ~ overlap (+4.7%) 22,621 ops/sec [21,950..23,120] → 22,264 ops/sec [21,893..22,430] ~ overlap (-1.6%)
identity method decorator 19,869 ops/sec [19,598..20,086] → 20,838 ops/sec [20,053..23,104] ~ overlap (+4.9%) 34,860 ops/sec [33,763..38,689] → 33,498 ops/sec [33,246..34,321] ~ overlap (-3.9%)
wrapping method decorator 16,922 ops/sec [15,672..18,451] → 16,321 ops/sec [15,718..19,629] ~ overlap (-3.5%) 26,399 ops/sec [24,898..28,809] → 25,673 ops/sec [24,799..31,498] ~ overlap (-2.8%)
stacked method decorators (x3) 11,896 ops/sec [11,178..12,660] → 11,476 ops/sec [11,315..11,610] ~ overlap (-3.5%) 18,273 ops/sec [17,097..19,794] → 19,467 ops/sec [17,802..19,685] ~ overlap (+6.5%)
identity field decorator 23,009 ops/sec [22,746..23,123] → 22,740 ops/sec [22,467..25,801] ~ overlap (-1.2%) 31,474 ops/sec [31,203..31,853] → 31,055 ops/sec [30,451..32,158] ~ overlap (-1.3%)
field initializer decorator 18,919 ops/sec [18,408..19,167] → 19,166 ops/sec [18,779..19,622] ~ overlap (+1.3%) 31,324 ops/sec [27,824..36,952] → 28,469 ops/sec [27,551..31,976] ~ overlap (-9.1%)
getter decorator (identity) 17,532 ops/sec [17,313..17,773] → 17,647 ops/sec [17,605..17,660] ~ overlap (+0.7%) 21,089 ops/sec [20,411..21,223] → 21,277 ops/sec [21,065..21,640] ~ overlap (+0.9%)
setter decorator (identity) 14,258 ops/sec [14,072..14,753] → 14,529 ops/sec [14,299..14,804] ~ overlap (+1.9%) 17,867 ops/sec [17,533..17,992] → 17,405 ops/sec [17,107..17,767] ~ overlap (-2.6%)
static method decorator 21,112 ops/sec [20,515..27,904] → 20,982 ops/sec [20,653..23,404] ~ overlap (-0.6%) 37,933 ops/sec [37,375..43,311] → 38,346 ops/sec [37,418..40,074] ~ overlap (+1.1%)
static field decorator 25,068 ops/sec [24,744..25,859] → 25,407 ops/sec [24,346..31,441] ~ overlap (+1.4%) 39,864 ops/sec [39,418..43,617] → 41,348 ops/sec [39,007..43,240] ~ overlap (+3.7%)
private method decorator 14,949 ops/sec [14,786..15,237] → 15,116 ops/sec [14,793..15,198] ~ overlap (+1.1%) 24,155 ops/sec [23,460..24,390] → 23,361 ops/sec [22,701..24,870] ~ overlap (-3.3%)
private field decorator 17,521 ops/sec [16,956..19,017] → 16,837 ops/sec [16,484..18,114] ~ overlap (-3.9%) 21,644 ops/sec [20,762..22,158] → 20,716 ops/sec [20,287..21,263] ~ overlap (-4.3%)
plain auto-accessor (no decorator) 29,708 ops/sec [29,428..29,885] → 28,914 ops/sec [28,767..29,151] 🔴 -2.7% 41,878 ops/sec [40,469..49,592] → 44,562 ops/sec [40,142..49,867] ~ overlap (+6.4%)
auto-accessor with decorator 16,887 ops/sec [16,372..19,672] → 17,193 ops/sec [16,414..17,422] ~ overlap (+1.8%) 23,646 ops/sec [22,953..30,376] → 24,451 ops/sec [23,736..27,714] ~ overlap (+3.4%)
decorator writing metadata 14,756 ops/sec [14,603..15,083] → 14,272 ops/sec [14,200..14,934] ~ overlap (-3.3%) 24,421 ops/sec [22,646..25,708] → 22,551 ops/sec [22,207..24,739] ~ overlap (-7.7%)
static getter read 31,234 ops/sec [31,151..31,401] → 31,824 ops/sec [31,254..32,118] ~ overlap (+1.9%) 72,455 ops/sec [66,640..77,282] → 62,803 ops/sec [62,149..76,679] ~ overlap (-13.3%)
static getter/setter pair 22,857 ops/sec [22,636..23,162] → 23,351 ops/sec [23,121..23,868] ~ overlap (+2.2%) 50,020 ops/sec [49,064..50,846] → 48,653 ops/sec [47,468..48,907] 🔴 -2.7%
inherited static getter 19,780 ops/sec [18,682..20,999] → 19,494 ops/sec [19,235..19,854] ~ overlap (-1.4%) 38,519 ops/sec [37,907..42,382] → 39,000 ops/sec [35,703..41,328] ~ overlap (+1.2%)
inherited static setter 22,284 ops/sec [21,187..24,272] → 21,000 ops/sec [20,816..21,790] ~ overlap (-5.8%) 38,968 ops/sec [38,674..40,589] → 40,215 ops/sec [39,864..46,072] ~ overlap (+3.2%)
inherited static getter with this binding 15,921 ops/sec [15,631..16,327] → 17,632 ops/sec [16,541..18,348] 🟢 +10.7% 33,159 ops/sec [32,362..33,794] → 31,319 ops/sec [29,404..32,429] ~ overlap (-5.5%)
closures.js — Interp: 11 unch. · avg -0.2% · Bytecode: 🟢 1, 10 unch. · avg +14.2%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
closure over single variable 24,289 ops/sec [24,025..25,898] → 24,660 ops/sec [23,655..26,388] ~ overlap (+1.5%) 133,092 ops/sec [130,808..137,282] → 131,524 ops/sec [130,708..132,333] ~ overlap (-1.2%)
closure over multiple variables 28,797 ops/sec [28,419..32,561] → 29,174 ops/sec [28,776..33,316] ~ overlap (+1.3%) 132,914 ops/sec [131,482..138,983] → 133,271 ops/sec [131,652..145,689] ~ overlap (+0.3%)
nested closures 32,075 ops/sec [31,508..32,967] → 32,559 ops/sec [31,488..32,709] ~ overlap (+1.5%) 120,520 ops/sec [118,364..178,634] → 121,865 ops/sec [119,228..123,320] ~ overlap (+1.1%)
function as argument 23,882 ops/sec [23,465..23,982] → 23,765 ops/sec [23,105..24,704] ~ overlap (-0.5%) 121,123 ops/sec [120,319..124,912] → 123,018 ops/sec [120,905..125,129] ~ overlap (+1.6%)
function returning function 29,613 ops/sec [29,322..30,261] → 29,939 ops/sec [29,380..37,366] ~ overlap (+1.1%) 135,031 ops/sec [131,546..142,277] → 136,262 ops/sec [134,403..142,847] ~ overlap (+0.9%)
compose two functions 19,032 ops/sec [18,816..22,305] → 18,995 ops/sec [18,696..20,503] ~ overlap (-0.2%) 81,867 ops/sec [81,678..85,526] → 82,564 ops/sec [79,295..83,210] ~ overlap (+0.9%)
fn.call 39,245 ops/sec [39,027..49,401] → 39,776 ops/sec [32,905..49,049] ~ overlap (+1.4%) 122,146 ops/sec [120,044..125,988] → 120,905 ops/sec [118,279..140,688] ~ overlap (-1.0%)
fn.apply 37,256 ops/sec [31,208..39,040] → 33,056 ops/sec [32,178..34,146] ~ overlap (-11.3%) 101,505 ops/sec [98,055..105,454] → 100,042 ops/sec [95,262..108,722] ~ overlap (-1.4%)
fn.bind 33,392 ops/sec [32,720..34,996] → 33,153 ops/sec [32,602..41,044] ~ overlap (-0.7%) 131,497 ops/sec [129,388..133,839] → 138,083 ops/sec [127,732..138,617] ~ overlap (+5.0%)
recursive sum to 50 2,885 ops/sec [2,830..2,958] → 2,937 ops/sec [2,825..3,070] ~ overlap (+1.8%) 24,540 ops/sec [22,918..31,438] → 61,496 ops/sec [60,480..66,848] 🟢 +150.6%
recursive tree traversal 4,592 ops/sec [4,422..4,766] → 4,655 ops/sec [4,517..4,799] ~ overlap (+1.4%) 17,738 ops/sec [16,931..19,769] → 17,651 ops/sec [17,206..17,759] ~ overlap (-0.5%)
collections.js — Interp: 🟢 1, 11 unch. · avg -0.2% · Bytecode: 12 unch. · avg -0.3%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
add 50 elements 2,562 ops/sec [2,518..2,633] → 2,634 ops/sec [2,615..2,650] ~ overlap (+2.8%) 4,609 ops/sec [4,486..4,670] → 4,672 ops/sec [4,583..4,896] ~ overlap (+1.4%)
has lookup (50 elements) 46,555 ops/sec [45,572..47,248] → 46,771 ops/sec [45,563..50,779] ~ overlap (+0.5%) 125,694 ops/sec [115,465..137,599] → 119,157 ops/sec [114,352..126,443] ~ overlap (-5.2%)
delete elements 13,105 ops/sec [12,721..13,168] → 13,361 ops/sec [12,948..13,652] ~ overlap (+2.0%) 24,040 ops/sec [23,226..29,510] → 23,750 ops/sec [22,680..24,807] ~ overlap (-1.2%)
forEach iteration 3,715 ops/sec [3,477..4,153] → 3,485 ops/sec [3,446..3,504] ~ overlap (-6.2%) 8,383 ops/sec [8,325..8,617] → 8,535 ops/sec [8,181..10,393] ~ overlap (+1.8%)
spread to array 10,479 ops/sec [9,947..11,536] → 10,563 ops/sec [10,494..10,669] ~ overlap (+0.8%) 74,707 ops/sec [73,893..75,309] → 73,593 ops/sec [72,035..88,160] ~ overlap (-1.5%)
deduplicate array 10,014 ops/sec [9,767..10,249] → 10,315 ops/sec [9,826..11,757] ~ overlap (+3.0%) 22,424 ops/sec [21,078..22,946] → 22,525 ops/sec [21,482..26,963] ~ overlap (+0.4%)
set 50 entries 1,949 ops/sec [1,935..1,966] → 2,007 ops/sec [1,967..2,475] 🟢 +3.0% 3,666 ops/sec [3,628..3,905] → 3,689 ops/sec [3,578..3,766] ~ overlap (+0.6%)
get lookup (50 entries) 46,795 ops/sec [46,547..47,147] → 45,935 ops/sec [45,604..48,143] ~ overlap (-1.8%) 113,536 ops/sec [106,083..149,751] → 111,187 ops/sec [105,679..116,355] ~ overlap (-2.1%)
has check 59,815 ops/sec [59,695..60,278] → 59,370 ops/sec [58,506..60,945] ~ overlap (-0.7%) 141,430 ops/sec [138,019..142,471] → 165,190 ops/sec [136,722..172,112] ~ overlap (+16.8%)
delete entries 13,535 ops/sec [12,090..14,403] → 12,164 ops/sec [11,816..12,636] ~ overlap (-10.1%) 22,092 ops/sec [20,869..23,444] → 21,008 ops/sec [20,748..21,186] ~ overlap (-4.9%)
forEach iteration 3,490 ops/sec [3,425..3,520] → 3,484 ops/sec [3,411..5,484] ~ overlap (-0.2%) 8,862 ops/sec [8,287..9,082] → 8,532 ops/sec [8,339..10,738] ~ overlap (-3.7%)
keys/values/entries 2,878 ops/sec [2,860..2,933] → 2,995 ops/sec [2,917..3,287] ~ overlap (+4.0%) 13,892 ops/sec [13,239..14,486] → 13,110 ops/sec [12,705..17,069] ~ overlap (-5.6%)
csv.js — Interp: 🟢 1, 🔴 1, 11 unch. · avg +0.6% · Bytecode: 🟢 1, 12 unch. · avg +1.7%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
parse simple 3-column CSV 38,156 ops/sec [37,418..38,425] → 38,979 ops/sec [38,543..39,660] 🟢 +2.2% 53,704 ops/sec [52,513..58,174] → 53,316 ops/sec [51,944..55,290] ~ overlap (-0.7%)
parse 10-row CSV 11,283 ops/sec [11,224..11,339] → 11,823 ops/sec [11,073..13,202] ~ overlap (+4.8%) 16,768 ops/sec [16,218..19,329] → 16,265 ops/sec [15,986..16,419] ~ overlap (-3.0%)
parse 100-row CSV 1,810 ops/sec [1,778..1,817] → 1,841 ops/sec [1,755..2,015] ~ overlap (+1.7%) 2,766 ops/sec [2,502..3,288] → 2,530 ops/sec [2,465..4,048] ~ overlap (-8.5%)
parse CSV with quoted fields 57,592 ops/sec [56,010..57,886] → 60,205 ops/sec [57,215..67,678] ~ overlap (+4.5%) 84,427 ops/sec [77,144..93,932] → 77,883 ops/sec [77,577..92,914] ~ overlap (-7.8%)
parse without headers (array of arrays) 5,419 ops/sec [5,295..5,625] → 5,531 ops/sec [5,353..7,663] ~ overlap (+2.1%) 7,897 ops/sec [7,372..9,659] → 7,456 ops/sec [7,368..7,632] ~ overlap (-5.6%)
parse with semicolon delimiter 8,432 ops/sec [7,786..10,684] → 8,383 ops/sec [7,993..13,518] ~ overlap (-0.6%) 11,562 ops/sec [11,476..13,702] → 14,117 ops/sec [11,891..14,136] ~ overlap (+22.1%)
stringify array of objects 41,141 ops/sec [39,760..48,743] → 40,938 ops/sec [40,167..42,327] ~ overlap (-0.5%) 64,830 ops/sec [63,960..87,318] → 64,350 ops/sec [62,647..66,819] ~ overlap (-0.7%)
stringify array of arrays 17,515 ops/sec [17,444..17,751] → 17,983 ops/sec [17,580..18,031] ~ overlap (+2.7%) 26,004 ops/sec [24,786..26,230] → 26,419 ops/sec [25,842..35,870] ~ overlap (+1.6%)
stringify with values needing escaping 23,136 ops/sec [22,211..24,687] → 22,596 ops/sec [22,290..23,410] ~ overlap (-2.3%) 34,241 ops/sec [33,519..35,871] → 34,057 ops/sec [32,769..36,336] ~ overlap (-0.5%)
reviver converts numbers 541 ops/sec [522..653] → 541 ops/sec [532..542] ~ overlap (-0.0%) 900 ops/sec [886..992] → 893 ops/sec [867..941] ~ overlap (-0.8%)
reviver filters empty to null 7,027 ops/sec [6,893..7,271] → 7,026 ops/sec [6,910..7,278] ~ overlap (-0.0%) 13,102 ops/sec [13,056..13,156] → 12,910 ops/sec [12,682..15,420] ~ overlap (-1.5%)
parse then stringify 6,769 ops/sec [6,667..6,921] → 6,615 ops/sec [6,573..6,634] 🔴 -2.3% 9,307 ops/sec [9,188..9,409] → 10,594 ops/sec [9,790..10,776] 🟢 +13.8%
stringify then parse 6,843 ops/sec [6,734..7,248] → 6,548 ops/sec [6,481..7,792] ~ overlap (-4.3%) 9,469 ops/sec [9,275..10,983] → 10,792 ops/sec [9,382..11,508] ~ overlap (+14.0%)
destructuring.js — Interp: 🔴 2, 20 unch. · avg -0.5% · Bytecode: 🟢 1, 🔴 1, 20 unch. · avg -0.4%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
simple array destructuring 51,532 ops/sec [50,972..51,758] → 51,346 ops/sec [50,890..51,730] ~ overlap (-0.4%) 111,999 ops/sec [102,156..118,529] → 103,243 ops/sec [102,107..133,081] ~ overlap (-7.8%)
with rest element 44,240 ops/sec [43,774..44,364] → 43,781 ops/sec [43,231..43,913] ~ overlap (-1.0%) 81,942 ops/sec [80,529..96,711] → 79,195 ops/sec [76,730..82,521] ~ overlap (-3.4%)
with defaults 58,423 ops/sec [53,710..62,417] → 53,170 ops/sec [52,820..55,559] ~ overlap (-9.0%) 110,860 ops/sec [104,925..114,300] → 106,675 ops/sec [105,811..107,231] ~ overlap (-3.8%)
skip elements 60,023 ops/sec [58,889..60,306] → 59,598 ops/sec [57,782..61,958] ~ overlap (-0.7%) 114,873 ops/sec [108,443..119,736] → 109,233 ops/sec [108,844..109,770] ~ overlap (-4.9%)
nested array destructuring 24,943 ops/sec [24,714..25,171] → 24,900 ops/sec [24,566..25,396] ~ overlap (-0.2%) 38,679 ops/sec [38,428..38,713] → 39,010 ops/sec [38,385..39,686] ~ overlap (+0.9%)
swap variables 71,369 ops/sec [71,184..71,575] → 71,006 ops/sec [69,050..73,929] ~ overlap (-0.5%) 155,627 ops/sec [154,337..157,787] → 157,986 ops/sec [156,475..158,994] ~ overlap (+1.5%)
simple object destructuring 63,182 ops/sec [61,951..64,900] → 64,055 ops/sec [63,144..65,675] ~ overlap (+1.4%) 128,840 ops/sec [128,385..147,550] → 129,790 ops/sec [126,421..167,909] ~ overlap (+0.7%)
with defaults 66,409 ops/sec [65,936..70,041] → 67,694 ops/sec [66,046..68,126] ~ overlap (+1.9%) 181,785 ops/sec [177,614..199,294] → 185,943 ops/sec [179,435..231,566] ~ overlap (+2.3%)
with renaming 73,600 ops/sec [71,545..73,765] → 70,003 ops/sec [69,224..70,134] 🔴 -4.9% 140,791 ops/sec [140,359..146,027] → 140,403 ops/sec [137,666..143,384] ~ overlap (-0.3%)
nested object destructuring 39,852 ops/sec [39,532..40,564] → 40,413 ops/sec [40,076..40,465] ~ overlap (+1.4%) 80,602 ops/sec [73,143..90,045] → 76,980 ops/sec [69,804..94,490] ~ overlap (-4.5%)
rest properties 36,314 ops/sec [35,570..37,805] → 36,063 ops/sec [35,999..36,399] ~ overlap (-0.7%) 67,186 ops/sec [58,656..81,887] → 58,949 ops/sec [57,112..72,515] ~ overlap (-12.3%)
object parameter 21,817 ops/sec [21,364..22,274] → 22,222 ops/sec [21,814..22,286] ~ overlap (+1.9%) 61,314 ops/sec [60,305..62,698] → 61,834 ops/sec [60,206..67,834] ~ overlap (+0.8%)
array parameter 25,660 ops/sec [25,499..25,811] → 25,524 ops/sec [24,840..26,019] ~ overlap (-0.5%) 56,593 ops/sec [55,198..61,584] → 58,398 ops/sec [53,617..71,964] ~ overlap (+3.2%)
mixed destructuring in map 5,983 ops/sec [5,939..7,349] → 6,043 ops/sec [6,016..6,085] ~ overlap (+1.0%) 13,308 ops/sec [13,058..13,485] → 12,881 ops/sec [12,795..13,053] 🔴 -3.2%
forEach with array destructuring 11,571 ops/sec [11,280..11,592] → 11,460 ops/sec [11,404..11,505] ~ overlap (-1.0%) 19,767 ops/sec [19,593..21,309] → 19,884 ops/sec [19,625..21,247] ~ overlap (+0.6%)
map with array destructuring 12,568 ops/sec [12,405..12,767] → 11,957 ops/sec [11,877..12,150] 🔴 -4.9% 17,326 ops/sec [17,212..19,581] → 18,088 ops/sec [17,942..18,630] ~ overlap (+4.4%)
filter with array destructuring 12,951 ops/sec [12,576..13,459] → 12,935 ops/sec [12,819..12,985] ~ overlap (-0.1%) 18,952 ops/sec [18,711..20,382] → 18,735 ops/sec [18,416..18,774] ~ overlap (-1.1%)
reduce with array destructuring 14,511 ops/sec [13,779..16,131] → 14,247 ops/sec [14,165..14,250] ~ overlap (-1.8%) 21,615 ops/sec [20,133..24,757] → 20,284 ops/sec [20,020..21,295] ~ overlap (-6.2%)
map with object destructuring 13,802 ops/sec [13,574..14,419] → 14,150 ops/sec [14,090..14,203] ~ overlap (+2.5%) 24,910 ops/sec [24,706..25,345] → 24,640 ops/sec [23,958..29,256] ~ overlap (-1.1%)
map with nested destructuring 11,750 ops/sec [11,215..13,135] → 11,857 ops/sec [11,411..11,884] ~ overlap (+0.9%) 22,964 ops/sec [22,612..35,401] → 24,657 ops/sec [24,471..24,802] ~ overlap (+7.4%)
map with rest in destructuring 6,797 ops/sec [6,586..6,901] → 6,925 ops/sec [6,584..7,507] ~ overlap (+1.9%) 8,443 ops/sec [8,383..9,658] → 9,281 ops/sec [9,089..9,950] ~ overlap (+9.9%)
map with defaults in destructuring 8,181 ops/sec [7,615..8,878] → 8,265 ops/sec [7,518..8,406] ~ overlap (+1.0%) 19,605 ops/sec [19,123..19,884] → 21,297 ops/sec [21,025..23,239] 🟢 +8.6%
fibonacci.js — Interp: 🔴 1, 7 unch. · avg -0.4% · Bytecode: 🟢 4, 4 unch. · avg +121.2%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
recursive fib(15) 88 ops/sec [81..99] → 82 ops/sec [82..83] ~ overlap (-6.2%) 639 ops/sec [602..760] → 2,118 ops/sec [2,109..3,436] 🟢 +231.4%
recursive fib(20) 8 ops/sec [8..8] → 8 ops/sec [8..8] ~ overlap (+2.6%) 64 ops/sec [55..75] → 192 ops/sec [192..192] 🟢 +201.6%
recursive fib(15) typed 81 ops/sec [78..82] → 81 ops/sec [81..83] ~ overlap (+0.5%) 594 ops/sec [589..626] → 2,027 ops/sec [1,905..2,311] 🟢 +241.1%
recursive fib(20) typed 8 ops/sec [7..8] → 8 ops/sec [7..8] ~ overlap (-1.3%) 56 ops/sec [54..57] → 211 ops/sec [174..244] 🟢 +278.1%
iterative fib(20) via reduce 3,996 ops/sec [3,899..4,626] → 4,188 ops/sec [3,971..4,206] ~ overlap (+4.8%) 7,964 ops/sec [7,504..9,758] → 8,790 ops/sec [7,481..10,183] ~ overlap (+10.4%)
iterator fib(20) 1,902 ops/sec [1,892..2,005] → 1,954 ops/sec [1,870..2,152] ~ overlap (+2.7%) 6,715 ops/sec [6,334..7,259] → 7,415 ops/sec [6,340..7,706] ~ overlap (+10.4%)
iterator fib(20) via Iterator.from + take 2,047 ops/sec [2,016..2,058] → 2,015 ops/sec [1,932..2,047] ~ overlap (-1.5%) 3,967 ops/sec [3,806..4,471] → 3,938 ops/sec [3,850..5,740] ~ overlap (-0.7%)
iterator fib(20) last value via reduce 1,776 ops/sec [1,760..1,811] → 1,686 ops/sec [1,607..1,700] 🔴 -5.1% 3,192 ops/sec [3,043..3,611] → 3,097 ops/sec [3,029..3,599] ~ overlap (-3.0%)
float16array.js — Interp: 🟢 5, 🔴 4, 23 unch. · avg +0.9% · Bytecode: 🟢 3, 🔴 4, 25 unch. · avg +0.5%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
new Float16Array(0) 99,974 ops/sec [99,268..103,499] → 104,047 ops/sec [102,773..105,350] ~ overlap (+4.1%) 177,798 ops/sec [174,055..181,768] → 176,967 ops/sec [172,292..243,935] ~ overlap (-0.5%)
new Float16Array(100) 99,213 ops/sec [98,770..99,521] → 99,574 ops/sec [99,018..100,805] ~ overlap (+0.4%) 177,632 ops/sec [165,704..179,306] → 171,199 ops/sec [166,713..177,881] ~ overlap (-3.6%)
new Float16Array(1000) 86,057 ops/sec [85,516..86,450] → 88,714 ops/sec [85,491..98,832] ~ overlap (+3.1%) 136,575 ops/sec [131,100..177,586] → 149,297 ops/sec [136,657..172,178] ~ overlap (+9.3%)
Float16Array.from([...100]) 1,257 ops/sec [1,235..1,324] → 1,280 ops/sec [1,215..1,638] ~ overlap (+1.8%) 1,890 ops/sec [1,685..1,987] → 1,918 ops/sec [1,752..2,508] ~ overlap (+1.5%)
Float16Array.of(1.5, 2.5, 3.5, 4.5, 5.5) 62,549 ops/sec [61,603..63,341] → 65,015 ops/sec [63,455..67,715] 🟢 +3.9% 107,758 ops/sec [100,401..116,567] → 101,067 ops/sec [98,524..101,492] ~ overlap (-6.2%)
new Float16Array(float64Array) 26,220 ops/sec [25,596..26,365] → 25,835 ops/sec [25,455..26,817] ~ overlap (-1.5%) 39,557 ops/sec [39,145..45,776] → 40,554 ops/sec [39,558..44,754] ~ overlap (+2.5%)
sequential write 100 elements 906 ops/sec [882..928] → 958 ops/sec [952..996] 🟢 +5.7% 6,859 ops/sec [6,821..6,870] → 8,175 ops/sec [7,833..8,255] 🟢 +19.2%
sequential read 100 elements 1,024 ops/sec [1,023..1,032] → 1,048 ops/sec [1,015..1,059] ~ overlap (+2.3%) 9,866 ops/sec [9,789..11,511] → 9,868 ops/sec [9,753..10,181] ~ overlap (+0.0%)
write special values (NaN, Inf, -0) 44,916 ops/sec [44,545..44,991] → 45,338 ops/sec [40,617..50,966] ~ overlap (+0.9%) 282,901 ops/sec [247,439..307,352] → 262,608 ops/sec [251,780..275,014] ~ overlap (-7.2%)
Float16Array write 901 ops/sec [897..905] → 896 ops/sec [885..914] ~ overlap (-0.5%) 6,920 ops/sec [6,772..6,937] → 8,130 ops/sec [7,862..8,482] 🟢 +17.5%
Float32Array write 905 ops/sec [902..906] → 898 ops/sec [894..902] 🔴 -0.7% 6,747 ops/sec [6,694..7,650] → 8,123 ops/sec [7,856..8,213] 🟢 +20.4%
Float64Array write 901 ops/sec [898..906] → 927 ops/sec [880..934] ~ overlap (+2.9%) 6,937 ops/sec [6,653..8,146] → 8,104 ops/sec [7,864..8,660] ~ overlap (+16.8%)
Float16Array read 1,016 ops/sec [1,005..1,020] → 1,009 ops/sec [1,001..1,014] ~ overlap (-0.7%) 10,584 ops/sec [10,378..10,709] → 10,474 ops/sec [10,352..12,475] ~ overlap (-1.0%)
Float32Array read 1,027 ops/sec [1,015..1,028] → 1,038 ops/sec [1,030..1,051] 🟢 +1.0% 10,389 ops/sec [10,346..10,495] → 10,632 ops/sec [10,440..10,818] ~ overlap (+2.3%)
Float64Array read 992 ops/sec [971..1,026] → 1,037 ops/sec [1,028..1,039] 🟢 +4.5% 10,409 ops/sec [10,281..10,620] → 10,409 ops/sec [10,227..10,677] ~ overlap (+0.0%)
fill(1.5) 6,627 ops/sec [6,597..6,706] → 6,601 ops/sec [6,561..6,613] ~ overlap (-0.4%) 10,248 ops/sec [10,089..10,283] → 9,713 ops/sec [9,285..9,860] 🔴 -5.2%
slice() 52,553 ops/sec [51,792..53,308] → 54,947 ops/sec [54,278..55,655] 🟢 +4.6% 90,697 ops/sec [89,314..92,257] → 83,414 ops/sec [81,441..84,477] 🔴 -8.0%
map(x => x * 2) 1,999 ops/sec [1,936..2,013] → 1,988 ops/sec [1,913..2,598] ~ overlap (-0.6%) 2,905 ops/sec [2,892..2,918] → 2,973 ops/sec [2,728..3,411] ~ overlap (+2.3%)
filter(x => x > 25) 1,946 ops/sec [1,926..3,193] → 1,946 ops/sec [1,923..1,967] ~ overlap (+0.0%) 3,187 ops/sec [2,942..3,512] → 2,980 ops/sec [2,803..3,283] ~ overlap (-6.5%)
reduce (sum) 1,879 ops/sec [1,861..2,302] → 1,896 ops/sec [1,730..2,067] ~ overlap (+0.9%) 2,728 ops/sec [2,580..2,907] → 2,759 ops/sec [2,659..3,042] ~ overlap (+1.1%)
sort() 22,313 ops/sec [21,982..22,380] → 23,291 ops/sec [21,962..23,718] ~ overlap (+4.4%) 33,004 ops/sec [32,182..35,253] → 33,485 ops/sec [31,833..35,114] ~ overlap (+1.5%)
indexOf() 27,104 ops/sec [26,947..27,170] → 26,451 ops/sec [25,995..26,856] 🔴 -2.4% 43,237 ops/sec [41,175..48,068] → 41,367 ops/sec [37,016..42,632] ~ overlap (-4.3%)
reverse() 28,065 ops/sec [27,942..28,442] → 26,793 ops/sec [26,661..26,998] 🔴 -4.5% 44,556 ops/sec [43,506..45,339] → 44,881 ops/sec [43,520..48,248] ~ overlap (+0.7%)
toReversed() 25,283 ops/sec [25,111..26,123] → 25,897 ops/sec [25,620..26,097] ~ overlap (+2.4%) 40,534 ops/sec [39,662..41,065] → 40,695 ops/sec [39,374..41,615] ~ overlap (+0.4%)
toSorted() 13,005 ops/sec [12,900..15,065] → 13,454 ops/sec [13,219..13,709] ~ overlap (+3.5%) 21,232 ops/sec [20,069..22,340] → 19,600 ops/sec [19,394..19,680] 🔴 -7.7%
create view over existing buffer 120,618 ops/sec [119,207..121,049] → 119,582 ops/sec [116,059..123,714] ~ overlap (-0.9%) 235,893 ops/sec [227,773..277,525] → 226,219 ops/sec [223,248..283,019] ~ overlap (-4.1%)
subarray() 58,576 ops/sec [57,469..59,682] → 56,244 ops/sec [54,495..56,813] 🔴 -4.0% 100,440 ops/sec [95,509..101,533] → 99,502 ops/sec [96,884..123,282] ~ overlap (-0.9%)
set() from array 64,952 ops/sec [64,084..65,423] → 65,661 ops/sec [64,690..65,707] ~ overlap (+1.1%) 112,600 ops/sec [110,985..116,159] → 112,117 ops/sec [108,602..118,840] ~ overlap (-0.4%)
for-of loop 1,325 ops/sec [1,290..1,435] → 1,326 ops/sec [1,303..1,353] ~ overlap (+0.1%) 13,000 ops/sec [12,553..13,297] → 12,690 ops/sec [12,533..14,211] ~ overlap (-2.4%)
spread into array 5,553 ops/sec [5,425..7,569] → 5,533 ops/sec [5,398..6,556] ~ overlap (-0.4%) 26,627 ops/sec [26,535..35,900] → 27,666 ops/sec [26,731..27,904] ~ overlap (+3.9%)
f16round(1.337) 136,848 ops/sec [133,640..161,522] → 134,971 ops/sec [134,139..139,654] ~ overlap (-1.4%) 319,565 ops/sec [288,358..349,406] → 285,219 ops/sec [283,529..286,815] 🔴 -10.7%
f16round over 100 values 870 ops/sec [851..888] → 866 ops/sec [862..873] ~ overlap (-0.5%) 4,311 ops/sec [3,718..4,600] → 3,660 ops/sec [3,573..3,926] ~ overlap (-15.1%)
for-in/for-in.js — Interp: 3 unch. · avg +1.5% · Bytecode: 🔴 1, 2 unch. · avg -1.4%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
for...in over 50 own keys 2,475 ops/sec [2,398..3,030] → 2,554 ops/sec [2,370..2,775] ~ overlap (+3.2%) 5,107 ops/sec [4,806..5,128] → 4,805 ops/sec [4,683..5,072] ~ overlap (-5.9%)
for...in over an 8-level chain of 50 shared keys 1,608 ops/sec [1,555..1,629] → 1,590 ops/sec [1,577..1,631] ~ overlap (-1.1%) 3,112 ops/sec [3,075..3,309] → 3,264 ops/sec [3,166..3,460] ~ overlap (+4.9%)
for...in over a 16-level chain of 100 shared keys 613 ops/sec [598..625] → 629 ops/sec [616..637] ~ overlap (+2.6%) 1,144 ops/sec [1,137..1,152] → 1,107 ops/sec [1,083..1,132] 🔴 -3.2%
for-of.js — Interp: 🔴 1, 6 unch. · avg -1.8% · Bytecode: 7 unch. · avg -2.5%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
for...of with 10-element array 11,202 ops/sec [11,065..11,979] → 11,285 ops/sec [10,983..12,414] ~ overlap (+0.7%) 113,920 ops/sec [110,780..128,409] → 113,394 ops/sec [110,029..130,475] ~ overlap (-0.5%)
for...of with 100-element array 1,321 ops/sec [1,274..1,340] → 1,356 ops/sec [1,292..1,361] ~ overlap (+2.6%) 20,609 ops/sec [17,416..23,667] → 17,782 ops/sec [17,446..20,318] ~ overlap (-13.7%)
for...of with string (10 chars) 8,098 ops/sec [7,970..8,210] → 8,378 ops/sec [8,030..8,475] ~ overlap (+3.5%) 28,112 ops/sec [27,833..38,867] → 27,997 ops/sec [27,396..34,829] ~ overlap (-0.4%)
for...of with Set (10 elements) 12,093 ops/sec [11,783..12,151] → 11,965 ops/sec [11,502..12,232] ~ overlap (-1.1%) 163,041 ops/sec [157,619..165,781] → 161,249 ops/sec [159,659..163,601] ~ overlap (-1.1%)
for...of with Map entries (10 entries) 6,104 ops/sec [6,081..6,150] → 6,150 ops/sec [6,119..7,189] ~ overlap (+0.7%) 15,586 ops/sec [14,865..15,603] → 15,858 ops/sec [15,435..15,952] ~ overlap (+1.7%)
for...of with destructuring 6,625 ops/sec [6,503..6,683] → 5,897 ops/sec [5,543..7,545] ~ overlap (-11.0%) 18,702 ops/sec [18,059..19,404] → 18,574 ops/sec [18,267..19,719] ~ overlap (-0.7%)
for-await-of with sync array 7,831 ops/sec [7,320..8,067] → 7,185 ops/sec [6,311..7,276] 🔴 -8.3% 2,720 ops/sec [2,632..2,762] → 2,635 ops/sec [2,624..2,648] ~ overlap (-3.2%)
generators.js — Interp: 🟢 1, 3 unch. · avg +6.7% · Bytecode: 🟢 1, 3 unch. · avg +3.8%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
manual next over object generator 582 ops/sec [581..604] → 583 ops/sec [559..853] ~ overlap (+0.1%) 1,299 ops/sec [1,290..1,308] → 1,338 ops/sec [1,308..1,453] 🟢 +3.0%
for...of over object generator 751 ops/sec [746..757] → 846 ops/sec [835..856] 🟢 +12.6% 1,869 ops/sec [1,799..2,275] → 1,941 ops/sec [1,868..1,946] ~ overlap (+3.9%)
yield delegation 754 ops/sec [741..915] → 863 ops/sec [823..874] ~ overlap (+14.4%) 1,873 ops/sec [1,829..2,134] → 2,009 ops/sec [1,864..2,178] ~ overlap (+7.2%)
class generator method 859 ops/sec [850..994] → 855 ops/sec [804..934] ~ overlap (-0.5%) 1,912 ops/sec [1,838..2,053] → 1,932 ops/sec [1,891..1,967] ~ overlap (+1.0%)
intl.js — Interp: 🟢 1, 5 unch. · avg +1.7% · Bytecode: 🔴 1, 5 unch. · avg -1.0%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
format decimal 20,959 ops/sec [20,472..21,487] → 20,453 ops/sec [19,166..23,067] ~ overlap (-2.4%) 38,265 ops/sec [37,969..38,835] → 38,093 ops/sec [37,602..41,062] ~ overlap (-0.4%)
format currency 17,259 ops/sec [16,856..17,510] → 19,203 ops/sec [19,089..20,055] 🟢 +11.3% 30,142 ops/sec [29,639..30,672] → 31,446 ops/sec [30,313..33,002] ~ overlap (+4.3%)
format UTC date 8,375 ops/sec [8,273..8,501] → 8,578 ops/sec [8,385..8,637] ~ overlap (+2.4%) 12,869 ops/sec [12,786..13,612] → 12,948 ops/sec [12,905..13,176] ~ overlap (+0.6%)
formatRange UTC dates 2,684 ops/sec [2,656..2,694] → 2,658 ops/sec [2,645..2,669] ~ overlap (-1.0%) 3,971 ops/sec [3,900..4,478] → 3,766 ops/sec [3,671..3,985] ~ overlap (-5.2%)
compare numeric strings 84,098 ops/sec [83,491..84,401] → 84,269 ops/sec [84,041..84,375] ~ overlap (+0.2%) 149,848 ops/sec [148,051..152,623] → 149,231 ops/sec [147,799..157,678] ~ overlap (-0.4%)
sort short string list 14,590 ops/sec [14,374..14,756] → 14,529 ops/sec [14,059..14,792] ~ overlap (-0.4%) 23,631 ops/sec [23,407..24,945] → 22,467 ops/sec [22,310..23,276] 🔴 -4.9%
iterators.js — Interp: 🔴 4, 38 unch. · avg -0.7% · Bytecode: 🔴 6, 36 unch. · avg -1.8%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
Iterator.from({next}).toArray() — 20 elements 2,994 ops/sec [2,607..3,292] → 3,021 ops/sec [2,917..3,041] ~ overlap (+0.9%) 6,543 ops/sec [6,459..6,596] → 6,118 ops/sec [6,035..6,243] 🔴 -6.5%
Iterator.from({next}).toArray() — 50 elements 1,226 ops/sec [1,216..1,268] → 1,221 ops/sec [1,205..1,265] ~ overlap (-0.4%) 2,705 ops/sec [2,704..2,711] → 2,511 ops/sec [2,394..2,580] 🔴 -7.2%
spread pre-wrapped iterator — 20 elements 2,583 ops/sec [2,555..2,636] → 2,573 ops/sec [2,507..2,606] ~ overlap (-0.4%) 6,935 ops/sec [6,841..6,963] → 6,383 ops/sec [6,022..6,561] 🔴 -8.0%
Iterator.from({next}).forEach — 50 elements 884 ops/sec [858..895] → 869 ops/sec [846..879] ~ overlap (-1.8%) 2,016 ops/sec [1,929..2,033] → 1,921 ops/sec [1,744..1,967] ~ overlap (-4.8%)
Iterator.from({next}).reduce — 50 elements 949 ops/sec [933..957] → 966 ops/sec [926..1,129] ~ overlap (+1.8%) 1,917 ops/sec [1,851..1,945] → 1,887 ops/sec [1,784..2,066] ~ overlap (-1.6%)
wrap array iterator 13,000 ops/sec [12,629..13,278] → 13,075 ops/sec [12,354..14,896] ~ overlap (+0.6%) 18,638 ops/sec [18,474..18,754] → 18,635 ops/sec [16,729..19,226] ~ overlap (-0.0%)
wrap plain {next()} object 2,093 ops/sec [2,006..2,135] → 2,098 ops/sec [2,045..2,331] ~ overlap (+0.3%) 4,344 ops/sec [4,248..4,364] → 4,513 ops/sec [4,328..5,069] ~ overlap (+3.9%)
map + toArray (50 elements) 730 ops/sec [719..742] → 709 ops/sec [704..740] ~ overlap (-2.9%) 1,200 ops/sec [1,180..1,243] → 1,193 ops/sec [1,147..1,209] ~ overlap (-0.6%)
filter + toArray (50 elements) 785 ops/sec [773..794] → 768 ops/sec [751..773] 🔴 -2.1% 1,390 ops/sec [1,347..1,459] → 1,381 ops/sec [1,357..1,394] ~ overlap (-0.7%)
take(10) + toArray (50 element source) 3,946 ops/sec [3,928..4,520] → 3,838 ops/sec [3,733..4,191] ~ overlap (-2.8%) 6,992 ops/sec [6,879..7,044] → 6,563 ops/sec [6,452..6,660] 🔴 -6.1%
drop(40) + toArray (50 element source) 1,071 ops/sec [1,039..1,157] → 1,029 ops/sec [999..1,191] ~ overlap (-4.0%) 2,045 ops/sec [2,008..2,084] → 1,969 ops/sec [1,785..2,086] ~ overlap (-3.7%)
chained map + filter + take (100 element source) 1,132 ops/sec [1,116..1,180] → 1,116 ops/sec [1,104..1,124] ~ overlap (-1.4%) 1,862 ops/sec [1,848..1,874] → 1,802 ops/sec [1,772..1,868] ~ overlap (-3.2%)
some + every (50 elements) 553 ops/sec [542..620] → 541 ops/sec [532..634] ~ overlap (-2.1%) 1,087 ops/sec [1,076..1,093] → 1,066 ops/sec [1,049..1,079] ~ overlap (-1.9%)
find (50 elements) 1,214 ops/sec [1,208..1,229] → 1,195 ops/sec [1,183..1,252] ~ overlap (-1.6%) 2,561 ops/sec [2,311..3,073] → 2,364 ops/sec [2,342..2,783] ~ overlap (-7.7%)
concat 2 arrays (10 + 10 elements) 5,246 ops/sec [5,163..5,382] → 5,208 ops/sec [5,013..5,342] ~ overlap (-0.7%) 7,103 ops/sec [6,853..7,123] → 6,853 ops/sec [6,718..6,995] ~ overlap (-3.5%)
concat 5 arrays (10 elements each) 2,362 ops/sec [2,273..2,646] → 2,207 ops/sec [2,158..2,269] 🔴 -6.5% 3,031 ops/sec [2,877..3,754] → 2,955 ops/sec [2,808..3,033] ~ overlap (-2.5%)
concat 2 arrays (20 + 20 elements) 2,998 ops/sec [2,929..3,103] → 2,851 ops/sec [2,816..2,902] 🔴 -4.9% 3,839 ops/sec [3,751..4,040] → 3,866 ops/sec [3,795..3,908] ~ overlap (+0.7%)
concat + filter + toArray (20 + 20 elements) 1,399 ops/sec [1,315..1,497] → 1,291 ops/sec [1,238..1,615] ~ overlap (-7.8%) 1,800 ops/sec [1,740..1,830] → 1,771 ops/sec [1,709..1,808] ~ overlap (-1.6%)
concat + map + take (20 + 20 elements, take 10) 3,072 ops/sec [3,043..3,314] → 3,134 ops/sec [3,096..3,827] ~ overlap (+2.0%) 4,298 ops/sec [4,143..5,015] → 4,240 ops/sec [4,195..4,310] ~ overlap (-1.4%)
concat Sets (15 + 15 elements) 4,137 ops/sec [3,905..4,609] → 3,948 ops/sec [3,838..4,805] ~ overlap (-4.6%) 5,180 ops/sec [4,853..5,597] → 5,061 ops/sec [5,023..5,238] ~ overlap (-2.3%)
concat boxed strings (13 + 13 characters) 4,156 ops/sec [4,080..4,708] → 4,095 ops/sec [4,033..4,193] ~ overlap (-1.5%) 5,486 ops/sec [5,392..5,531] → 5,352 ops/sec [5,350..5,370] 🔴 -2.4%
zip 2 arrays (10 + 10 elements) 9,502 ops/sec [9,365..10,160] → 9,533 ops/sec [9,268..9,814] ~ overlap (+0.3%) 12,807 ops/sec [12,398..13,038] → 12,782 ops/sec [12,363..13,559] ~ overlap (-0.2%)
zip 3 arrays (10 elements each) 9,004 ops/sec [8,704..9,074] → 8,937 ops/sec [8,717..9,003] ~ overlap (-0.7%) 11,798 ops/sec [11,678..11,919] → 11,891 ops/sec [11,642..11,903] ~ overlap (+0.8%)
zip 2 arrays (20 + 20 elements) 5,703 ops/sec [5,542..6,823] → 5,828 ops/sec [5,490..8,133] ~ overlap (+2.2%) 7,477 ops/sec [7,290..8,471] → 7,262 ops/sec [7,211..7,306] ~ overlap (-2.9%)
zip 2 arrays (50 + 50 elements) 2,810 ops/sec [2,540..3,066] → 2,595 ops/sec [2,590..2,664] ~ overlap (-7.7%) 3,397 ops/sec [3,329..3,512] → 3,359 ops/sec [3,171..3,972] ~ overlap (-1.1%)
zip shortest mode (20 + 10 elements) 9,312 ops/sec [9,106..10,522] → 9,440 ops/sec [9,184..9,678] ~ overlap (+1.4%) 12,412 ops/sec [12,101..12,865] → 12,508 ops/sec [12,298..13,896] ~ overlap (+0.8%)
zip longest mode (10 + 20 elements) 5,464 ops/sec [5,302..5,624] → 5,505 ops/sec [5,383..7,286] ~ overlap (+0.8%) 7,750 ops/sec [6,975..8,661] → 7,625 ops/sec [6,877..9,488] ~ overlap (-1.6%)
zip strict mode (20 + 20 elements) 5,594 ops/sec [5,439..6,181] → 5,576 ops/sec [5,498..6,442] ~ overlap (-0.3%) 7,545 ops/sec [7,035..8,147] → 7,209 ops/sec [7,066..9,066] ~ overlap (-4.5%)
zip + map + toArray (20 + 20 elements) 1,879 ops/sec [1,846..2,052] → 1,881 ops/sec [1,840..2,137] ~ overlap (+0.1%) 2,342 ops/sec [2,324..3,519] → 2,357 ops/sec [2,334..2,390] ~ overlap (+0.7%)
zip + filter + toArray (20 + 20 elements) 1,990 ops/sec [1,924..2,109] → 1,990 ops/sec [1,937..2,024] ~ overlap (-0.0%) 2,639 ops/sec [2,541..2,703] → 2,576 ops/sec [2,547..2,584] ~ overlap (-2.4%)
zip Sets (15 + 15 elements) 7,751 ops/sec [7,654..7,916] → 7,788 ops/sec [7,656..7,886] ~ overlap (+0.5%) 10,121 ops/sec [9,797..10,660] → 9,947 ops/sec [9,680..10,018] ~ overlap (-1.7%)
zipKeyed 2 keys (10 elements each) 10,078 ops/sec [8,857..10,990] → 9,482 ops/sec [9,010..11,597] ~ overlap (-5.9%) 12,083 ops/sec [11,969..16,047] → 11,975 ops/sec [11,859..11,992] ~ overlap (-0.9%)
zipKeyed 3 keys (20 elements each) 4,751 ops/sec [4,627..5,442] → 4,657 ops/sec [4,538..4,708] ~ overlap (-2.0%) 6,218 ops/sec [6,046..7,415] → 6,355 ops/sec [6,157..7,627] ~ overlap (+2.2%)
zipKeyed longest mode (10 + 20 elements) 5,231 ops/sec [5,047..5,734] → 5,205 ops/sec [5,144..5,241] ~ overlap (-0.5%) 6,817 ops/sec [6,713..6,897] → 6,750 ops/sec [6,495..7,217] ~ overlap (-1.0%)
zipKeyed strict mode (20 + 20 elements) 5,184 ops/sec [5,137..5,404] → 5,296 ops/sec [5,168..5,328] ~ overlap (+2.2%) 6,619 ops/sec [6,458..7,474] → 6,930 ops/sec [6,821..7,615] ~ overlap (+4.7%)
zipKeyed + filter + map (20 elements) 1,701 ops/sec [1,690..1,707] → 1,723 ops/sec [1,633..1,729] ~ overlap (+1.3%) 2,528 ops/sec [2,497..2,535] → 2,501 ops/sec [2,445..2,518] ~ overlap (-1.0%)
array.values().map().filter().toArray() 700 ops/sec [696..702] → 699 ops/sec [680..1,033] ~ overlap (-0.3%) 996 ops/sec [960..1,036] → 1,065 ops/sec [927..1,142] ~ overlap (+6.9%)
array.values().take(5).toArray() 11,437 ops/sec [11,270..11,566] → 11,871 ops/sec [11,135..12,816] ~ overlap (+3.8%) 15,802 ops/sec [15,658..15,970] → 16,219 ops/sec [14,025..16,873] ~ overlap (+2.6%)
array.values().drop(45).toArray() 2,432 ops/sec [2,385..2,724] → 3,118 ops/sec [2,387..3,893] ~ overlap (+28.2%) 3,613 ops/sec [3,186..3,761] → 3,128 ops/sec [3,087..3,304] ~ overlap (-13.4%)
map.entries() chained helpers 1,050 ops/sec [977..1,112] → 980 ops/sec [953..987] ~ overlap (-6.6%) 1,269 ops/sec [1,261..1,406] → 1,238 ops/sec [1,220..1,246] 🔴 -2.4%
set.values() chained helpers 1,771 ops/sec [1,753..1,789] → 1,677 ops/sec [1,671..1,715] 🔴 -5.3% 2,415 ops/sec [2,371..2,536] → 2,405 ops/sec [2,372..2,487] ~ overlap (-0.4%)
string iterator map + toArray 1,755 ops/sec [1,731..1,848] → 1,705 ops/sec [1,682..1,739] ~ overlap (-2.9%) 2,310 ops/sec [2,293..2,386] → 2,301 ops/sec [2,237..2,666] ~ overlap (-0.4%)
json.js — Interp: 🔴 3, 20 unch. · avg -0.4% · Bytecode: 🟢 2, 21 unch. · avg +0.8%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
parse simple object 36,253 ops/sec [35,804..38,082] → 35,492 ops/sec [35,316..35,527] 🔴 -2.1% 56,937 ops/sec [55,026..58,133] → 55,349 ops/sec [53,639..68,468] ~ overlap (-2.8%)
parse nested object 22,442 ops/sec [22,084..22,599] → 22,064 ops/sec [21,923..22,340] ~ overlap (-1.7%) 33,772 ops/sec [33,568..35,363] → 34,492 ops/sec [34,208..35,687] ~ overlap (+2.1%)
parse array of objects 13,805 ops/sec [13,662..14,672] → 13,936 ops/sec [13,112..14,058] ~ overlap (+0.9%) 20,108 ops/sec [19,983..20,376] → 20,466 ops/sec [20,214..22,108] ~ overlap (+1.8%)
parse large flat object 14,598 ops/sec [14,392..14,838] → 14,385 ops/sec [14,119..14,446] ~ overlap (-1.5%) 22,770 ops/sec [21,385..22,940] → 21,780 ops/sec [21,414..22,227] ~ overlap (-4.3%)
parse mixed types 12,691 ops/sec [12,379..13,516] → 12,419 ops/sec [11,770..15,277] ~ overlap (-2.1%) 19,133 ops/sec [18,502..20,519] → 19,832 ops/sec [17,601..20,301] ~ overlap (+3.7%)
stringify simple object 47,474 ops/sec [47,080..48,513] → 46,004 ops/sec [45,612..47,050] 🔴 -3.1% 69,776 ops/sec [68,774..76,753] → 69,529 ops/sec [66,563..70,737] ~ overlap (-0.4%)
stringify nested object 26,731 ops/sec [25,920..28,072] → 28,863 ops/sec [26,639..36,734] ~ overlap (+8.0%) 38,934 ops/sec [37,635..48,353] → 38,235 ops/sec [35,545..41,755] ~ overlap (-1.8%)
stringify array of objects 12,835 ops/sec [11,818..15,015] → 11,853 ops/sec [11,657..13,397] ~ overlap (-7.7%) 19,031 ops/sec [18,397..23,769] → 19,263 ops/sec [18,433..20,950] ~ overlap (+1.2%)
stringify mixed types 23,939 ops/sec [23,513..25,036] → 23,110 ops/sec [22,525..25,305] ~ overlap (-3.5%) 33,363 ops/sec [32,561..33,471] → 33,890 ops/sec [32,245..41,656] ~ overlap (+1.6%)
reviver doubles numbers 7,952 ops/sec [7,908..8,136] → 7,985 ops/sec [7,895..8,106] ~ overlap (+0.4%) 15,201 ops/sec [14,791..18,174] → 15,289 ops/sec [14,891..19,540] ~ overlap (+0.6%)
reviver filters properties 7,920 ops/sec [7,856..7,972] → 7,936 ops/sec [7,830..7,976] ~ overlap (+0.2%) 13,733 ops/sec [13,358..14,452] → 13,939 ops/sec [13,667..14,106] ~ overlap (+1.5%)
reviver on nested object 9,107 ops/sec [9,053..9,130] → 9,103 ops/sec [8,974..10,332] ~ overlap (-0.0%) 15,910 ops/sec [15,722..18,825] → 16,348 ops/sec [15,980..20,246] ~ overlap (+2.8%)
reviver on array 4,935 ops/sec [4,921..4,956] → 4,849 ops/sec [4,768..4,853] 🔴 -1.7% 9,857 ops/sec [9,524..10,364] → 9,747 ops/sec [9,256..11,198] ~ overlap (-1.1%)
replacer function doubles numbers 10,122 ops/sec [10,041..10,214] → 9,979 ops/sec [9,822..10,070] ~ overlap (-1.4%) 20,539 ops/sec [18,201..22,805] → 20,278 ops/sec [19,362..22,066] ~ overlap (-1.3%)
replacer function excludes properties 13,501 ops/sec [12,811..16,156] → 13,289 ops/sec [12,987..14,672] ~ overlap (-1.6%) 26,391 ops/sec [24,567..27,336] → 26,608 ops/sec [26,130..26,943] ~ overlap (+0.8%)
array replacer (allowlist) 36,101 ops/sec [34,840..37,085] → 36,122 ops/sec [35,278..37,127] ~ overlap (+0.1%) 51,742 ops/sec [50,688..54,539] → 51,616 ops/sec [51,227..52,443] ~ overlap (-0.2%)
stringify with 2-space indent 27,506 ops/sec [27,061..32,440] → 28,771 ops/sec [27,273..29,906] ~ overlap (+4.6%) 39,187 ops/sec [38,890..42,064] → 39,969 ops/sec [39,222..40,299] ~ overlap (+2.0%)
stringify with tab indent 27,542 ops/sec [26,886..28,674] → 27,460 ops/sec [27,302..29,446] ~ overlap (-0.3%) 39,748 ops/sec [38,866..53,477] → 40,116 ops/sec [39,799..41,388] ~ overlap (+0.9%)
stringify deeply nested object with 2-space indent 4,057 ops/sec [3,923..4,378] → 4,265 ops/sec [4,055..5,313] ~ overlap (+5.1%) 5,965 ops/sec [5,938..5,985] → 6,214 ops/sec [5,931..6,525] ~ overlap (+4.2%)
stringify deeply nested array with 2-space indent 5,816 ops/sec [5,704..6,176] → 5,934 ops/sec [5,925..5,961] ~ overlap (+2.0%) 9,292 ops/sec [8,743..9,531] → 9,115 ops/sec [9,079..9,141] ~ overlap (-1.9%)
stringify very deeply nested object with 2-space indent 699 ops/sec [671..709] → 699 ops/sec [659..757] ~ overlap (+0.1%) 944 ops/sec [908..1,094] → 956 ops/sec [944..1,159] ~ overlap (+1.2%)
parse then stringify 12,854 ops/sec [12,295..12,864] → 12,807 ops/sec [12,424..16,663] ~ overlap (-0.4%) 19,583 ops/sec [19,450..19,713] → 20,384 ops/sec [20,272..23,670] 🟢 +4.1%
stringify then parse 7,904 ops/sec [7,521..9,429] → 7,625 ops/sec [7,266..7,711] ~ overlap (-3.5%) 11,440 ops/sec [11,369..11,504] → 11,833 ops/sec [11,532..11,902] 🟢 +3.4%
jsx.jsx — Interp: 🟢 5, 16 unch. · avg +2.1% · Bytecode: 🔴 1, 20 unch. · avg -0.6%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
simple element 67,597 ops/sec [67,200..67,967] → 68,127 ops/sec [66,917..73,145] ~ overlap (+0.8%) 125,225 ops/sec [121,564..126,463] → 119,701 ops/sec [111,695..126,449] ~ overlap (-4.4%)
self-closing element 73,911 ops/sec [67,932..82,050] → 69,126 ops/sec [60,107..71,576] ~ overlap (-6.5%) 129,381 ops/sec [126,699..131,692] → 128,705 ops/sec [126,123..131,191] ~ overlap (-0.5%)
element with string attribute 59,409 ops/sec [58,437..60,855] → 60,005 ops/sec [59,538..60,394] ~ overlap (+1.0%) 95,677 ops/sec [94,688..98,473] → 98,771 ops/sec [96,091..107,411] ~ overlap (+3.2%)
element with multiple attributes 52,031 ops/sec [51,405..65,813] → 51,970 ops/sec [51,431..52,641] ~ overlap (-0.1%) 72,149 ops/sec [71,012..84,267] → 73,481 ops/sec [71,502..86,008] ~ overlap (+1.8%)
element with expression attribute 54,151 ops/sec [49,808..56,418] → 52,187 ops/sec [51,646..52,810] ~ overlap (-3.6%) 100,441 ops/sec [97,557..122,699] → 101,511 ops/sec [97,033..112,749] ~ overlap (+1.1%)
text child 66,816 ops/sec [65,839..68,704] → 69,788 ops/sec [68,635..70,395] ~ overlap (+4.4%) 130,382 ops/sec [127,207..151,327] → 127,049 ops/sec [125,112..131,686] ~ overlap (-2.6%)
expression child 60,163 ops/sec [60,032..60,370] → 61,703 ops/sec [61,598..62,060] 🟢 +2.6% 118,976 ops/sec [116,099..120,825] → 122,201 ops/sec [118,269..128,823] ~ overlap (+2.7%)
mixed text and expression 58,530 ops/sec [58,154..59,085] → 59,144 ops/sec [58,259..60,006] ~ overlap (+1.0%) 115,382 ops/sec [108,246..127,582] → 116,691 ops/sec [104,557..159,857] ~ overlap (+1.1%)
nested elements (3 levels) 27,480 ops/sec [26,698..29,240] → 28,911 ops/sec [28,094..37,537] ~ overlap (+5.2%) 49,299 ops/sec [48,407..53,066] → 49,776 ops/sec [47,661..58,570] ~ overlap (+1.0%)
sibling children 21,080 ops/sec [20,910..21,359] → 21,644 ops/sec [21,043..22,326] ~ overlap (+2.7%) 35,301 ops/sec [34,960..56,640] → 35,635 ops/sec [34,780..39,319] ~ overlap (+0.9%)
component element 48,364 ops/sec [47,824..54,369] → 50,554 ops/sec [50,181..50,801] ~ overlap (+4.5%) 89,202 ops/sec [86,629..92,185] → 91,365 ops/sec [89,917..93,232] ~ overlap (+2.4%)
component with children 31,206 ops/sec [30,517..31,475] → 32,523 ops/sec [31,524..35,696] 🟢 +4.2% 56,262 ops/sec [55,125..57,652] → 57,008 ops/sec [55,092..57,702] ~ overlap (+1.3%)
dotted component 42,954 ops/sec [42,022..53,394] → 43,371 ops/sec [42,426..50,695] ~ overlap (+1.0%) 73,445 ops/sec [67,418..79,290] → 72,559 ops/sec [69,863..80,456] ~ overlap (-1.2%)
empty fragment 72,224 ops/sec [69,798..99,402] → 71,260 ops/sec [70,957..71,716] ~ overlap (-1.3%) 140,911 ops/sec [132,504..148,729] → 139,044 ops/sec [132,654..200,690] ~ overlap (-1.3%)
fragment with children 22,235 ops/sec [20,242..31,121] → 21,603 ops/sec [20,976..24,512] ~ overlap (-2.8%) 39,217 ops/sec [35,406..40,154] → 36,966 ops/sec [36,188..40,905] ~ overlap (-5.7%)
spread attributes 32,644 ops/sec [31,429..33,012] → 33,263 ops/sec [32,392..36,469] ~ overlap (+1.9%) 49,919 ops/sec [49,519..53,842] → 51,318 ops/sec [50,034..56,036] ~ overlap (+2.8%)
spread with overrides 28,352 ops/sec [27,689..28,545] → 29,222 ops/sec [28,721..31,723] 🟢 +3.1% 43,910 ops/sec [43,274..47,532] → 42,371 ops/sec [42,065..42,669] 🔴 -3.5%
shorthand props 47,029 ops/sec [46,679..47,965] → 50,110 ops/sec [48,952..50,355] 🟢 +6.6% 85,081 ops/sec [80,943..89,171] → 81,917 ops/sec [81,085..82,182] ~ overlap (-3.7%)
nav bar structure 10,289 ops/sec [10,057..10,392] → 10,681 ops/sec [10,474..11,032] 🟢 +3.8% 17,216 ops/sec [16,938..18,111] → 16,423 ops/sec [16,000..17,242] ~ overlap (-4.6%)
card component tree 11,516 ops/sec [11,327..13,956] → 12,321 ops/sec [11,824..13,256] ~ overlap (+7.0%) 19,197 ops/sec [18,327..19,389] → 18,479 ops/sec [18,154..18,740] ~ overlap (-3.7%)
10 list items via Array.from 4,829 ops/sec [4,760..5,898] → 5,296 ops/sec [5,027..6,279] ~ overlap (+9.7%) 6,987 ops/sec [6,812..8,583] → 7,028 ops/sec [6,885..7,346] ~ overlap (+0.6%)
modules.js — Interp: 9 unch. · avg +1.0% · Bytecode: 🔴 1, 8 unch. · avg -2.4%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
call imported function 103,034 ops/sec [101,768..104,815] → 106,205 ops/sec [104,308..108,205] ~ overlap (+3.1%) 50,459 ops/sec [44,850..64,077] → 46,536 ops/sec [45,390..54,999] ~ overlap (-7.8%)
call two imported functions 59,535 ops/sec [59,096..60,559] → 60,849 ops/sec [59,907..61,854] ~ overlap (+2.2%) 26,145 ops/sec [23,631..27,440] → 24,827 ops/sec [23,655..26,504] ~ overlap (-5.0%)
read imported constant 274,625 ops/sec [267,921..283,071] → 281,803 ops/sec [273,837..315,287] ~ overlap (+2.6%) 49,374 ops/sec [47,678..55,759] → 50,130 ops/sec [47,561..66,008] ~ overlap (+1.5%)
read imported string 284,741 ops/sec [263,799..324,096] → 295,021 ops/sec [268,822..313,251] ~ overlap (+3.6%) 53,323 ops/sec [47,278..55,782] → 51,994 ops/sec [47,606..55,733] ~ overlap (-2.5%)
read JSON string property 280,657 ops/sec [264,755..308,602] → 279,465 ops/sec [276,808..283,432] ~ overlap (-0.4%) 48,691 ops/sec [47,612..52,106] → 48,844 ops/sec [48,113..52,871] ~ overlap (+0.3%)
read JSON number property 268,714 ops/sec [264,169..269,487] → 275,842 ops/sec [265,707..276,613] ~ overlap (+2.7%) 47,962 ops/sec [46,079..49,577] → 48,601 ops/sec [47,186..50,530] ~ overlap (+1.3%)
read JSON boolean property 287,934 ops/sec [269,059..333,432] → 279,282 ops/sec [267,567..348,364] ~ overlap (-3.0%) 51,056 ops/sec [48,671..53,483] → 49,757 ops/sec [47,907..51,752] ~ overlap (-2.5%)
read JSON array property 278,984 ops/sec [274,168..284,899] → 270,035 ops/sec [263,693..279,217] ~ overlap (-3.2%) 50,863 ops/sec [49,094..54,079] → 48,008 ops/sec [47,888..48,153] 🔴 -5.6%
read multiple JSON properties 142,218 ops/sec [132,764..175,348] → 144,867 ops/sec [136,803..164,622] ~ overlap (+1.9%) 16,958 ops/sec [16,582..17,007] → 16,777 ops/sec [16,721..21,272] ~ overlap (-1.1%)
numbers.js — Interp: 12 unch. · avg +0.7% · Bytecode: 12 unch. · avg +0.7%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
integer arithmetic 64,630 ops/sec [62,838..69,878] → 64,577 ops/sec [63,828..68,322] ~ overlap (-0.1%) 598,674 ops/sec [562,746..841,934] → 639,290 ops/sec [562,897..690,150] ~ overlap (+6.8%)
floating point arithmetic 75,698 ops/sec [74,928..79,342] → 77,219 ops/sec [73,677..80,546] ~ overlap (+2.0%) 479,451 ops/sec [461,395..509,006] → 490,169 ops/sec [441,606..603,697] ~ overlap (+2.2%)
number coercion 16,133 ops/sec [15,475..16,215] → 15,654 ops/sec [15,034..16,008] ~ overlap (-3.0%) 28,968 ops/sec [27,852..29,143] → 28,111 ops/sec [27,020..34,442] ~ overlap (-3.0%)
toFixed 27,139 ops/sec [27,083..31,030] → 27,103 ops/sec [26,820..27,431] ~ overlap (-0.1%) 47,678 ops/sec [46,562..59,020] → 51,226 ops/sec [47,013..60,360] ~ overlap (+7.4%)
toString 42,503 ops/sec [40,933..44,585] → 41,461 ops/sec [40,264..49,683] ~ overlap (-2.5%) 82,164 ops/sec [78,709..90,011] → 82,306 ops/sec [78,482..92,078] ~ overlap (+0.2%)
toString non-integer (shortest round-trip) 8,841 ops/sec [8,780..9,194] → 8,745 ops/sec [8,623..8,882] ~ overlap (-1.1%) 21,329 ops/sec [21,034..27,009] → 21,957 ops/sec [20,635..22,516] ~ overlap (+2.9%)
valueOf 55,312 ops/sec [54,311..70,665] → 56,012 ops/sec [54,471..68,037] ~ overlap (+1.3%) 117,502 ops/sec [112,444..179,761] → 111,076 ops/sec [109,347..112,527] ~ overlap (-5.5%)
toPrecision 25,817 ops/sec [25,036..34,391] → 25,913 ops/sec [25,481..33,277] ~ overlap (+0.4%) 45,788 ops/sec [42,235..58,150] → 44,893 ops/sec [43,618..53,358] ~ overlap (-2.0%)
Number.isNaN 55,412 ops/sec [50,280..57,724] → 57,280 ops/sec [56,018..59,105] ~ overlap (+3.4%) 121,781 ops/sec [121,608..123,072] → 121,081 ops/sec [117,026..123,532] ~ overlap (-0.6%)
Number.isFinite 53,817 ops/sec [53,101..56,857] → 56,043 ops/sec [54,397..60,513] ~ overlap (+4.1%) 118,084 ops/sec [110,731..127,549] → 114,857 ops/sec [112,347..118,096] ~ overlap (-2.7%)
Number.isInteger 58,068 ops/sec [56,132..59,300] → 59,425 ops/sec [57,070..68,245] ~ overlap (+2.3%) 111,890 ops/sec [111,588..142,058] → 115,898 ops/sec [115,270..116,085] ~ overlap (+3.6%)
Number.parseInt and parseFloat 22,079 ops/sec [21,322..25,299] → 22,540 ops/sec [20,938..26,822] ~ overlap (+2.1%) 34,969 ops/sec [34,663..36,296] → 34,589 ops/sec [34,028..35,901] ~ overlap (-1.1%)
objects.js — Interp: 🔴 1, 6 unch. · avg +3.1% · Bytecode: 7 unch. · avg -2.2%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
create simple object 129,005 ops/sec [125,080..137,151] → 130,831 ops/sec [128,403..147,396] ~ overlap (+1.4%) 182,756 ops/sec [176,921..186,442] → 174,620 ops/sec [172,569..179,086] ~ overlap (-4.5%)
create nested object 75,537 ops/sec [71,967..89,041] → 76,922 ops/sec [74,849..86,359] ~ overlap (+1.8%) 89,125 ops/sec [81,227..91,503] → 82,793 ops/sec [81,312..85,133] ~ overlap (-7.1%)
create 50 objects via Array.from 2,764 ops/sec [2,651..3,624] → 2,618 ops/sec [2,546..2,636] 🔴 -5.3% 2,913 ops/sec [2,845..3,068] → 2,886 ops/sec [2,812..3,002] ~ overlap (-0.9%)
property read 100,321 ops/sec [97,486..101,783] → 100,508 ops/sec [100,088..101,700] ~ overlap (+0.2%) 491,599 ops/sec [478,678..503,181] → 531,334 ops/sec [456,880..586,668] ~ overlap (+8.1%)
Object.keys 63,524 ops/sec [62,769..64,832] → 66,517 ops/sec [62,800..79,614] ~ overlap (+4.7%) 108,774 ops/sec [103,607..112,430] → 107,838 ops/sec [107,424..118,714] ~ overlap (-0.9%)
Object.entries 33,651 ops/sec [33,295..34,515] → 38,214 ops/sec [33,072..43,805] ~ overlap (+13.6%) 52,466 ops/sec [50,884..63,577] → 51,932 ops/sec [49,812..54,752] ~ overlap (-1.0%)
spread operator 42,100 ops/sec [40,653..47,093] → 44,460 ops/sec [41,066..51,465] ~ overlap (+5.6%) 72,170 ops/sec [67,332..76,578] → 65,649 ops/sec [63,705..68,359] ~ overlap (-9.0%)
promises.js — Interp: 🟢 2, 10 unch. · avg +4.1% · Bytecode: 12 unch. · avg -2.4%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
Promise.resolve(value) 60,011 ops/sec [59,428..61,935] → 61,894 ops/sec [60,537..63,411] ~ overlap (+3.1%) 92,684 ops/sec [91,781..93,267] → 90,606 ops/sec [88,947..114,019] ~ overlap (-2.2%)
new Promise(resolve => resolve(value)) 44,308 ops/sec [42,050..47,973] → 44,359 ops/sec [43,719..44,556] ~ overlap (+0.1%) 70,480 ops/sec [69,926..72,321] → 72,044 ops/sec [68,562..77,622] ~ overlap (+2.2%)
Promise.reject(reason) 59,866 ops/sec [58,649..60,373] → 62,308 ops/sec [62,004..62,491] 🟢 +4.1% 95,021 ops/sec [90,762..140,307] → 91,539 ops/sec [90,938..115,696] ~ overlap (-3.7%)
resolve + then (1 handler) 20,309 ops/sec [19,575..23,540] → 21,969 ops/sec [20,339..25,990] ~ overlap (+8.2%) 33,972 ops/sec [30,563..37,657] → 31,622 ops/sec [29,896..33,550] ~ overlap (-6.9%)
resolve + then chain (3 deep) 8,611 ops/sec [8,555..9,006] → 9,035 ops/sec [8,713..9,240] ~ overlap (+4.9%) 12,779 ops/sec [12,652..13,178] → 12,492 ops/sec [12,341..12,730] ~ overlap (-2.2%)
resolve + then chain (10 deep) 2,832 ops/sec [2,823..2,893] → 3,019 ops/sec [2,857..3,158] ~ overlap (+6.6%) 4,249 ops/sec [4,167..4,308] → 4,713 ops/sec [4,155..5,863] ~ overlap (+10.9%)
reject + catch + then 11,936 ops/sec [11,828..13,805] → 12,615 ops/sec [12,011..13,788] ~ overlap (+5.7%) 17,235 ops/sec [17,150..20,624] → 17,426 ops/sec [17,215..17,553] ~ overlap (+1.1%)
resolve + finally + then 5,953 ops/sec [5,597..6,363] → 6,150 ops/sec [5,747..6,499] ~ overlap (+3.3%) 8,091 ops/sec [7,919..8,168] → 7,956 ops/sec [7,865..8,058] ~ overlap (-1.7%)
Promise.all (5 resolved) 3,892 ops/sec [3,784..4,170] → 3,891 ops/sec [3,807..4,631] ~ overlap (-0.0%) 5,961 ops/sec [5,596..7,128] → 5,429 ops/sec [5,308..6,318] ~ overlap (-8.9%)
Promise.race (5 resolved) 4,425 ops/sec [4,320..5,027] → 4,580 ops/sec [4,485..4,812] ~ overlap (+3.5%) 6,586 ops/sec [6,274..7,491] → 6,295 ops/sec [6,256..6,398] ~ overlap (-4.4%)
Promise.allSettled (5 mixed) 3,319 ops/sec [3,302..3,341] → 3,471 ops/sec [3,398..3,870] 🟢 +4.6% 5,486 ops/sec [4,658..5,585] → 4,775 ops/sec [4,679..4,882] ~ overlap (-13.0%)
Promise.any (5 mixed) 3,944 ops/sec [3,895..4,918] → 4,160 ops/sec [3,982..4,277] ~ overlap (+5.5%) 5,627 ops/sec [5,564..6,521] → 5,656 ops/sec [5,542..5,696] ~ overlap (+0.5%)
property-access.js — Interp: 5 unch. · avg +2.8% · Bytecode: 5 unch. · avg -1.6%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
class instance fields across 1000 instances 114 ops/sec [109..134] → 120 ops/sec [115..136] ~ overlap (+5.6%) 1,245 ops/sec [1,206..1,336] → 1,255 ops/sec [1,206..1,586] ~ overlap (+0.8%)
object literal fields across 1000 literals 115 ops/sec [110..127] → 116 ops/sec [114..127] ~ overlap (+0.6%) 1,289 ops/sec [1,187..1,681] → 1,245 ops/sec [1,195..1,369] ~ overlap (-3.4%)
mixed-shape literals across 1000 literals 117 ops/sec [114..132] → 119 ops/sec [114..126] ~ overlap (+1.2%) 910 ops/sec [874..1,260] → 902 ops/sec [887..931] ~ overlap (-0.9%)
own-class method across 1000 instances 74 ops/sec [71..74] → 75 ops/sec [73..105] ~ overlap (+0.8%) 565 ops/sec [538..576] → 565 ops/sec [542..575] ~ overlap (-0.0%)
inherited method across 1000 instances 80 ops/sec [78..81] → 85 ops/sec [81..110] ~ overlap (+6.0%) 642 ops/sec [588..705] → 615 ops/sec [599..632] ~ overlap (-4.3%)
regexp.js — Interp: 13 unch. · avg +0.2% · Bytecode: 🟢 1, 12 unch. · avg -1.0%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
regex literal creation 7,736 ops/sec [7,546..8,152] → 7,981 ops/sec [7,761..8,492] ~ overlap (+3.2%) 300,277 ops/sec [275,461..343,233] → 285,483 ops/sec [271,046..339,442] ~ overlap (-4.9%)
new RegExp(pattern, flags) 7,849 ops/sec [7,031..9,921] → 7,802 ops/sec [7,459..12,274] ~ overlap (-0.6%) 11,102 ops/sec [10,879..11,159] → 11,364 ops/sec [11,310..11,523] 🟢 +2.4%
RegExp(existingRegex) returns the same regex 139,363 ops/sec [134,656..160,924] → 142,379 ops/sec [138,120..143,497] ~ overlap (+2.2%) 349,150 ops/sec [301,279..377,846] → 341,768 ops/sec [320,859..398,442] ~ overlap (-2.1%)
test() on a global regex 63,405 ops/sec [61,724..77,786] → 63,970 ops/sec [60,902..66,215] ~ overlap (+0.9%) 117,163 ops/sec [110,500..118,442] → 119,239 ops/sec [116,018..155,017] ~ overlap (+1.8%)
exec() with capture groups 36,427 ops/sec [35,169..40,049] → 36,283 ops/sec [34,378..41,450] ~ overlap (-0.4%) 59,769 ops/sec [57,412..76,687] → 57,782 ops/sec [55,843..77,385] ~ overlap (-3.3%)
toString() 49,880 ops/sec [49,304..52,765] → 49,081 ops/sec [48,689..53,637] ~ overlap (-1.6%) 85,792 ops/sec [83,362..86,229] → 85,818 ops/sec [80,292..104,784] ~ overlap (+0.0%)
match() with global regex 21,769 ops/sec [21,497..22,402] → 22,148 ops/sec [21,790..23,331] ~ overlap (+1.7%) 38,611 ops/sec [37,915..39,505] → 39,360 ops/sec [37,934..42,249] ~ overlap (+1.9%)
match() with many global results 1,120 ops/sec [1,116..1,128] → 1,100 ops/sec [1,095..1,148] ~ overlap (-1.8%) 1,632 ops/sec [1,624..1,711] → 1,664 ops/sec [1,655..1,712] ~ overlap (+2.0%)
matchAll() with capture groups 7,540 ops/sec [7,128..7,863] → 7,581 ops/sec [7,304..7,962] ~ overlap (+0.5%) 16,498 ops/sec [15,454..17,911] → 15,691 ops/sec [15,506..23,601] ~ overlap (-4.9%)
replace() with global regex 20,759 ops/sec [20,235..21,972] → 20,834 ops/sec [20,412..21,244] ~ overlap (+0.4%) 36,932 ops/sec [35,187..49,729] → 36,356 ops/sec [35,555..43,056] ~ overlap (-1.6%)
replace() with many global results 831 ops/sec [822..845] → 812 ops/sec [811..847] ~ overlap (-2.3%) 1,322 ops/sec [1,233..1,532] → 1,245 ops/sec [1,224..1,619] ~ overlap (-5.8%)
search() with regex 39,841 ops/sec [39,142..40,266] → 40,591 ops/sec [39,609..41,011] ~ overlap (+1.9%) 78,661 ops/sec [74,956..81,606] → 78,188 ops/sec [76,345..79,485] ~ overlap (-0.6%)
split() with regex separator 10,267 ops/sec [9,871..11,024] → 10,174 ops/sec [9,759..10,200] ~ overlap (-0.9%) 15,218 ops/sec [15,099..15,645] → 15,641 ops/sec [15,046..16,365] ~ overlap (+2.8%)
strings.js — Interp: 🟢 3, 🔴 3, 13 unch. · avg +1.9% · Bytecode: 🟢 1, 18 unch. · avg -0.7%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
string concatenation 84,322 ops/sec [83,360..93,257] → 89,914 ops/sec [88,601..103,299] ~ overlap (+6.6%) 672,802 ops/sec [627,214..755,372] → 654,273 ops/sec [609,962..693,383] ~ overlap (-2.8%)
template literal 147,541 ops/sec [145,327..158,492] → 157,306 ops/sec [151,987..188,499] ~ overlap (+6.6%) 521,876 ops/sec [516,115..526,777] → 530,850 ops/sec [497,182..542,166] ~ overlap (+1.7%)
string repeat 95,714 ops/sec [91,958..131,115] → 110,012 ops/sec [105,277..110,466] ~ overlap (+14.9%) 175,348 ops/sec [169,960..193,120] → 173,798 ops/sec [171,958..174,267] ~ overlap (-0.9%)
split and join 42,073 ops/sec [40,577..42,488] → 42,643 ops/sec [41,263..42,838] ~ overlap (+1.4%) 84,890 ops/sec [77,156..87,270] → 79,723 ops/sec [78,830..84,364] ~ overlap (-6.1%)
indexOf and includes 39,406 ops/sec [38,812..39,718] → 41,184 ops/sec [40,656..46,841] 🟢 +4.5% 77,265 ops/sec [71,722..80,688] → 71,958 ops/sec [69,002..75,810] ~ overlap (-6.9%)
toUpperCase and toLowerCase 37,291 ops/sec [36,573..37,446] → 38,607 ops/sec [38,332..41,735] 🟢 +3.5% 66,257 ops/sec [64,299..81,871] → 64,945 ops/sec [64,128..77,184] ~ overlap (-2.0%)
slice and substring 36,303 ops/sec [35,932..43,387] → 36,735 ops/sec [36,396..36,839] ~ overlap (+1.2%) 72,441 ops/sec [69,637..74,147] → 72,744 ops/sec [65,858..75,559] ~ overlap (+0.4%)
trim operations 41,529 ops/sec [40,219..43,992] → 41,881 ops/sec [41,046..44,862] ~ overlap (+0.8%) 78,129 ops/sec [77,493..82,634] → 81,513 ops/sec [80,394..83,676] ~ overlap (+4.3%)
replace and replaceAll 48,275 ops/sec [47,439..50,906] → 47,754 ops/sec [47,353..47,871] ~ overlap (-1.1%) 84,205 ops/sec [82,058..89,488] → 84,221 ops/sec [80,244..89,375] ~ overlap (+0.0%)
startsWith and endsWith 31,658 ops/sec [30,656..32,861] → 31,367 ops/sec [30,861..34,261] ~ overlap (-0.9%) 59,166 ops/sec [55,884..62,006] → 60,883 ops/sec [57,171..63,577] ~ overlap (+2.9%)
padStart and padEnd 51,181 ops/sec [48,645..53,413] → 50,574 ops/sec [48,714..53,143] ~ overlap (-1.2%) 96,846 ops/sec [86,250..124,653] → 99,418 ops/sec [96,453..125,133] ~ overlap (+2.7%)
identity tag, no substitutions 103,276 ops/sec [100,529..105,401] → 114,956 ops/sec [103,039..124,359] ~ overlap (+11.3%) 239,511 ops/sec [216,727..275,236] → 224,638 ops/sec [219,494..239,807] ~ overlap (-6.2%)
tag with 1 substitution 23,235 ops/sec [22,963..29,374] → 21,798 ops/sec [21,475..22,924] 🔴 -6.2% 42,948 ops/sec [42,837..43,307] → 43,907 ops/sec [43,220..54,547] ~ overlap (+2.2%)
tag with 3 substitutions 13,054 ops/sec [12,874..14,292] → 12,317 ops/sec [12,185..12,482] 🔴 -5.6% 26,996 ops/sec [26,241..28,340] → 26,786 ops/sec [25,678..30,640] ~ overlap (-0.8%)
tag with 6 substitutions 7,949 ops/sec [7,744..8,060] → 7,600 ops/sec [7,588..7,612] 🔴 -4.4% 15,846 ops/sec [15,426..16,184] → 15,856 ops/sec [15,792..15,952] ~ overlap (+0.1%)
String.raw, no substitutions 92,170 ops/sec [90,952..92,624] → 89,437 ops/sec [87,478..94,120] ~ overlap (-3.0%) 129,225 ops/sec [128,204..129,880] → 130,459 ops/sec [130,269..134,610] 🟢 +1.0%
String.raw, 2 substitutions 63,761 ops/sec [63,231..65,278] → 64,810 ops/sec [63,198..72,069] ~ overlap (+1.6%) 104,242 ops/sec [101,954..110,870] → 103,106 ops/sec [102,628..103,328] ~ overlap (-1.1%)
tag accessing .raw array 37,836 ops/sec [37,410..38,078] → 39,351 ops/sec [39,278..39,522] 🟢 +4.0% 67,074 ops/sec [66,526..67,238] → 66,712 ops/sec [66,538..67,409] ~ overlap (-0.5%)
method as tag (this binding) 16,072 ops/sec [16,028..16,116] → 16,312 ops/sec [15,704..16,870] ~ overlap (+1.5%) 32,989 ops/sec [32,720..33,131] → 32,695 ops/sec [31,641..34,678] ~ overlap (-0.9%)
temporal.js — Interp: 6 unch. · avg +1.5% · Bytecode: 🟢 1, 5 unch. · avg -1.1%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
PlainDate.add({ months: 1 }) 37,848 ops/sec [37,064..38,318] → 38,841 ops/sec [38,150..42,613] ~ overlap (+2.6%) 59,985 ops/sec [58,720..62,933] → 59,830 ops/sec [58,349..61,063] ~ overlap (-0.3%)
PlainDate.until(..., { largestUnit: 'months' }) 45,713 ops/sec [44,153..60,249] → 45,094 ops/sec [40,050..48,500] ~ overlap (-1.4%) 71,239 ops/sec [70,032..72,247] → 75,668 ops/sec [73,104..89,856] 🟢 +6.2%
Duration.total days relative to PlainDate 38,245 ops/sec [36,713..38,646] → 38,970 ops/sec [37,530..40,442] ~ overlap (+1.9%) 59,870 ops/sec [56,334..60,577] → 57,594 ops/sec [56,589..59,252] ~ overlap (-3.8%)
Duration.round to hours 30,604 ops/sec [30,514..31,971] → 31,563 ops/sec [31,265..31,696] ~ overlap (+3.1%) 48,379 ops/sec [45,734..51,923] → 47,853 ops/sec [45,320..50,456] ~ overlap (-1.1%)
ZonedDateTime.from named time zone 8,628 ops/sec [8,326..8,999] → 8,661 ops/sec [7,799..9,526] ~ overlap (+0.4%) 13,935 ops/sec [12,942..14,834] → 13,189 ops/sec [12,943..17,887] ~ overlap (-5.3%)
ZonedDateTime.since across DST 9,692 ops/sec [9,584..10,459] → 9,920 ops/sec [9,719..10,619] ~ overlap (+2.3%) 15,265 ops/sec [15,134..15,290] → 14,936 ops/sec [14,524..17,508] ~ overlap (-2.1%)
tsv.js — Interp: 9 unch. · avg +0.8% · Bytecode: 🟢 1, 8 unch. · avg +2.4%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
parse simple 3-column TSV 39,608 ops/sec [38,620..41,119] → 40,298 ops/sec [39,104..43,832] ~ overlap (+1.7%) 49,411 ops/sec [47,718..50,359] → 51,160 ops/sec [50,602..57,463] 🟢 +3.5%
parse 10-row TSV 11,898 ops/sec [10,800..12,508] → 11,385 ops/sec [11,163..13,725] ~ overlap (-4.3%) 14,582 ops/sec [14,448..15,715] → 15,641 ops/sec [15,411..16,184] ~ overlap (+7.3%)
parse 100-row TSV 1,795 ops/sec [1,751..2,069] → 1,857 ops/sec [1,818..2,096] ~ overlap (+3.4%) 2,317 ops/sec [2,241..3,008] → 2,664 ops/sec [2,474..2,715] ~ overlap (+15.0%)
parse TSV with backslash-escaped fields 9,000 ops/sec [8,901..11,342] → 9,313 ops/sec [9,243..9,371] ~ overlap (+3.5%) 12,410 ops/sec [11,822..13,829] → 13,188 ops/sec [12,306..13,635] ~ overlap (+6.3%)
parse without headers (array of arrays) 5,752 ops/sec [5,364..6,104] → 5,654 ops/sec [5,484..5,668] ~ overlap (-1.7%) 7,244 ops/sec [6,829..8,262] → 7,408 ops/sec [7,200..8,072] ~ overlap (+2.3%)
stringify array of objects 11,994 ops/sec [11,707..13,624] → 12,118 ops/sec [11,829..12,282] ~ overlap (+1.0%) 18,230 ops/sec [17,723..18,396] → 19,282 ops/sec [17,950..20,009] ~ overlap (+5.8%)
stringify array of arrays 3,153 ops/sec [3,020..3,373] → 3,340 ops/sec [3,077..3,397] ~ overlap (+5.9%) 4,841 ops/sec [4,616..5,243] → 4,582 ops/sec [4,568..4,617] ~ overlap (-5.4%)
stringify with values needing escaping 9,889 ops/sec [9,857..10,026] → 9,721 ops/sec [9,634..9,877] ~ overlap (-1.7%) 17,371 ops/sec [14,836..19,593] → 15,006 ops/sec [14,933..16,458] ~ overlap (-13.6%)
parse then stringify 3,903 ops/sec [3,877..3,975] → 3,857 ops/sec [3,802..3,938] ~ overlap (-1.2%) 5,355 ops/sec [5,316..5,402] → 5,398 ops/sec [5,312..5,471] ~ overlap (+0.8%)
typed-arrays.js — Interp: 🟢 7, 🔴 1, 14 unch. · avg +5.2% · Bytecode: 🟢 1, 🔴 8, 13 unch. · avg -4.1%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
new Int32Array(0) 101,709 ops/sec [100,672..126,098] → 105,012 ops/sec [102,000..105,043] ~ overlap (+3.2%) 179,177 ops/sec [175,909..193,482] → 177,186 ops/sec [174,040..188,099] ~ overlap (-1.1%)
new Int32Array(100) 96,357 ops/sec [94,725..114,491] → 98,976 ops/sec [96,663..110,833] ~ overlap (+2.7%) 167,725 ops/sec [164,313..267,646] → 164,313 ops/sec [159,414..176,880] ~ overlap (-2.0%)
new Int32Array(1000) 74,352 ops/sec [73,491..90,921] → 75,197 ops/sec [72,988..79,648] ~ overlap (+1.1%) 119,205 ops/sec [117,819..145,765] → 114,747 ops/sec [110,657..118,816] ~ overlap (-3.7%)
new Float64Array(100) 93,918 ops/sec [92,278..99,297] → 95,974 ops/sec [95,795..96,307] ~ overlap (+2.2%) 155,552 ops/sec [154,605..159,785] → 151,244 ops/sec [149,506..158,905] ~ overlap (-2.8%)
Int32Array.from([...]) 1,201 ops/sec [1,170..1,233] → 1,233 ops/sec [1,217..1,238] ~ overlap (+2.7%) 1,786 ops/sec [1,765..1,813] → 1,646 ops/sec [1,591..1,668] 🔴 -7.9%
Int32Array.of(1, 2, 3, 4, 5) 62,819 ops/sec [61,708..63,886] → 63,682 ops/sec [63,492..64,327] ~ overlap (+1.4%) 108,875 ops/sec [106,487..109,144] → 105,921 ops/sec [105,318..108,577] ~ overlap (-2.7%)
sequential write 100 elements 987 ops/sec [966..995] → 977 ops/sec [972..980] ~ overlap (-1.0%) 10,109 ops/sec [9,894..10,167] → 10,060 ops/sec [9,987..10,119] ~ overlap (-0.5%)
sequential read 100 elements 1,028 ops/sec [1,025..1,038] → 1,040 ops/sec [1,030..1,130] ~ overlap (+1.2%) 11,422 ops/sec [11,320..11,566] → 11,359 ops/sec [11,147..11,591] ~ overlap (-0.6%)
Float64Array write 100 elements 910 ops/sec [851..921] → 901 ops/sec [884..995] ~ overlap (-1.0%) 6,933 ops/sec [6,863..7,033] → 8,130 ops/sec [8,097..8,135] 🟢 +17.3%
fill(42) 5,768 ops/sec [5,742..5,830] → 10,203 ops/sec [10,124..10,239] 🟢 +76.9% 8,204 ops/sec [8,110..8,355] → 8,461 ops/sec [8,284..8,464] ~ overlap (+3.1%)
slice() 51,497 ops/sec [51,029..52,343] → 51,734 ops/sec [51,170..51,862] ~ overlap (+0.5%) 85,185 ops/sec [83,535..86,500] → 84,108 ops/sec [83,310..84,439] ~ overlap (-1.3%)
map(x => x * 2) 1,899 ops/sec [1,871..1,930] → 2,209 ops/sec [1,953..2,229] 🟢 +16.3% 2,963 ops/sec [2,946..2,995] → 2,879 ops/sec [2,747..2,895] 🔴 -2.8%
filter(x => x > 50) 1,939 ops/sec [1,902..3,225] → 1,977 ops/sec [1,952..1,986] ~ overlap (+2.0%) 3,136 ops/sec [3,104..3,226] → 3,029 ops/sec [2,984..3,043] 🔴 -3.4%
reduce (sum) 1,892 ops/sec [1,856..1,896] → 1,913 ops/sec [1,882..1,940] ~ overlap (+1.1%) 4,865 ops/sec [4,832..4,895] → 2,764 ops/sec [2,742..2,804] 🔴 -43.2%
sort() 37,168 ops/sec [36,848..37,288] → 37,670 ops/sec [36,826..37,733] ~ overlap (+1.4%) 50,782 ops/sec [50,754..50,821] → 30,901 ops/sec [30,772..31,309] 🔴 -39.1%
indexOf() 45,435 ops/sec [45,366..45,822] → 27,820 ops/sec [26,676..28,784] 🔴 -38.8% 42,208 ops/sec [42,005..42,475] → 39,606 ops/sec [39,530..40,703] 🔴 -6.2%
reverse() 45,744 ops/sec [26,399..45,894] → 26,818 ops/sec [26,687..46,201] ~ overlap (-41.4%) 38,896 ops/sec [38,745..44,508] → 40,412 ops/sec [40,009..41,286] ~ overlap (+3.9%)
create view over existing buffer 122,301 ops/sec [120,878..125,463] → 199,988 ops/sec [199,244..201,233] 🟢 +63.5% 231,342 ops/sec [227,337..233,066] → 234,292 ops/sec [223,560..246,539] ~ overlap (+1.3%)
subarray() 90,120 ops/sec [89,255..91,112] → 93,880 ops/sec [93,544..94,414] 🟢 +4.2% 99,667 ops/sec [98,951..105,032] → 98,806 ops/sec [98,178..100,208] ~ overlap (-0.9%)
set() from array 105,435 ops/sec [105,185..105,941] → 106,995 ops/sec [106,896..107,105] 🟢 +1.5% 157,333 ops/sec [109,136..183,370] → 177,476 ops/sec [108,998..180,027] ~ overlap (+12.8%)
for-of loop 2,050 ops/sec [2,025..2,074] → 2,154 ops/sec [2,135..2,163] 🟢 +5.1% 23,991 ops/sec [23,952..24,135] → 23,153 ops/sec [22,778..23,257] 🔴 -3.5%
spread into array 8,348 ops/sec [8,291..8,436] → 9,107 ops/sec [9,034..9,135] 🟢 +9.1% 41,602 ops/sec [41,431..41,847] → 38,797 ops/sec [38,637..39,289] 🔴 -6.7%
uint8array-encoding.js — Interp: 🟢 4, 🔴 1, 13 unch. · avg +15.7% · Bytecode: 🟢 6, 🔴 1, 11 unch. · avg +12.7%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
short (5 bytes) 129,251 ops/sec [126,544..131,013] → 130,575 ops/sec [128,463..134,575] ~ overlap (+1.0%) 227,706 ops/sec [226,727..228,221] → 235,885 ops/sec [229,392..242,154] 🟢 +3.6%
medium (450 bytes) 89,363 ops/sec [88,231..91,085] → 90,525 ops/sec [88,778..102,244] ~ overlap (+1.3%) 133,492 ops/sec [132,582..135,202] → 135,977 ops/sec [134,173..136,417] ~ overlap (+1.9%)
large (4096 bytes) 24,192 ops/sec [23,861..25,886] → 23,870 ops/sec [23,573..24,109] ~ overlap (-1.3%) 31,743 ops/sec [30,245..33,151] → 32,246 ops/sec [32,007..34,669] ~ overlap (+1.6%)
base64url alphabet 74,023 ops/sec [67,841..87,307] → 67,866 ops/sec [66,972..81,456] ~ overlap (-8.3%) 92,370 ops/sec [91,407..95,388] → 97,245 ops/sec [94,637..98,576] ~ overlap (+5.3%)
omitPadding 89,618 ops/sec [88,625..90,171] → 89,919 ops/sec [87,942..92,874] ~ overlap (+0.3%) 137,491 ops/sec [134,282..150,207] → 138,024 ops/sec [135,808..143,464] ~ overlap (+0.4%)
short (8 chars) 96,218 ops/sec [95,215..96,700] → 95,330 ops/sec [93,856..97,835] ~ overlap (-0.9%) 155,572 ops/sec [154,051..156,536] → 150,936 ops/sec [146,945..155,095] ~ overlap (-3.0%)
medium (600 chars) 19,166 ops/sec [18,677..20,229] → 18,996 ops/sec [18,839..20,235] ~ overlap (-0.9%) 27,436 ops/sec [27,175..27,560] → 27,690 ops/sec [27,285..28,724] ~ overlap (+0.9%)
large (5464 chars) 2,650 ops/sec [2,462..2,662] → 2,532 ops/sec [2,518..2,551] ~ overlap (-4.5%) 3,591 ops/sec [3,550..3,923] → 3,647 ops/sec [3,582..5,590] ~ overlap (+1.5%)
short (5 bytes) 131,797 ops/sec [129,498..133,874] → 130,827 ops/sec [127,671..133,433] ~ overlap (-0.7%) 388,979 ops/sec [239,886..392,779] → 407,554 ops/sec [244,813..411,652] ~ overlap (+4.8%)
medium (450 bytes) 79,555 ops/sec [78,811..80,642] → 82,906 ops/sec [80,598..86,126] ~ overlap (+4.2%) 196,078 ops/sec [193,068..197,476] → 124,495 ops/sec [121,582..125,036] 🔴 -36.5%
large (4096 bytes) 19,606 ops/sec [19,402..19,760] → 19,714 ops/sec [19,501..33,439] ~ overlap (+0.6%) 40,225 ops/sec [24,871..40,424] → 25,268 ops/sec [24,966..26,430] ~ overlap (-37.2%)
short (10 chars) 108,454 ops/sec [108,132..109,954] → 170,194 ops/sec [170,080..170,495] 🟢 +56.9% 167,983 ops/sec [167,482..170,368] → 274,615 ops/sec [172,691..277,670] 🟢 +63.5%
medium (900 chars) 81,976 ops/sec [80,832..83,031] → 132,241 ops/sec [130,901..132,833] 🟢 +61.3% 119,851 ops/sec [118,652..121,517] → 198,516 ops/sec [197,289..199,588] 🟢 +65.6%
large (8192 chars) 27,711 ops/sec [25,239..28,067] → 48,695 ops/sec [48,242..49,132] 🟢 +75.7% 33,336 ops/sec [32,942..33,824] → 59,207 ops/sec [58,962..59,351] 🟢 +77.6%
setFromBase64 (450 bytes) 19,023 ops/sec [18,580..19,463] → 30,964 ops/sec [30,756..31,126] 🟢 +62.8% 26,541 ops/sec [26,485..26,647] → 42,807 ops/sec [42,446..43,022] 🟢 +61.3%
setFromHex (450 bytes) 21,114 ops/sec [21,073..21,245] → 21,560 ops/sec [21,130..35,647] ~ overlap (+2.1%) 31,450 ops/sec [30,812..31,709] → 47,827 ops/sec [47,502..47,948] 🟢 +52.1%
toBase64 → fromBase64 (450 bytes) 16,612 ops/sec [16,245..17,112] → 27,957 ops/sec [16,853..28,362] ~ overlap (+68.3%) 37,551 ops/sec [37,004..37,638] → 37,116 ops/sec [24,091..37,647] ~ overlap (-1.2%)
toHex → fromHex (450 bytes) 77,223 ops/sec [76,092..77,729] → 50,074 ops/sec [49,662..50,105] 🔴 -35.2% 106,289 ops/sec [105,715..106,669] → 70,364 ops/sec [68,244..111,806] ~ overlap (-33.8%)
weak-collections.js — Interp: 🟢 4, 🔴 1, 10 unch. · avg -0.1% · Bytecode: 🟢 8, 🔴 1, 6 unch. · avg +32.4%
Benchmark Interpreted (main → PR) Δ Bytecode (main → PR) Δ
constructor from 50 entries 7,339 ops/sec [7,152..7,492] → 7,565 ops/sec [7,432..8,217] ~ overlap (+3.1%) 11,491 ops/sec [11,220..11,678] → 18,433 ops/sec [18,303..18,942] 🟢 +60.4%
set 50 object keys 2,461 ops/sec [2,419..2,522] → 2,513 ops/sec [2,500..2,538] ~ overlap (+2.1%) 4,695 ops/sec [4,625..4,737] → 4,692 ops/sec [4,630..4,832] ~ overlap (-0.1%)
get lookups (50 entries) 56,209 ops/sec [34,288..56,854] → 35,159 ops/sec [34,530..38,730] ~ overlap (-37.4%) 99,509 ops/sec [98,058..103,100] → 175,865 ops/sec [172,788..178,064] 🟢 +76.7%
has checks (50 entries) 46,288 ops/sec [45,552..75,328] → 57,488 ops/sec [46,502..78,286] ~ overlap (+24.2%) 121,702 ops/sec [121,250..124,511] → 216,834 ops/sec [214,796..218,201] 🟢 +78.2%
delete entries 2,323 ops/sec [2,299..2,338] → 2,387 ops/sec [2,326..2,405] ~ overlap (+2.8%) 4,449 ops/sec [4,377..4,510] → 7,562 ops/sec [7,549..7,582] 🟢 +70.0%
non-registered symbol keys 5,630 ops/sec [5,540..6,263] → 5,851 ops/sec [5,779..5,897] ~ overlap (+3.9%) 10,661 ops/sec [10,556..10,690] → 11,016 ops/sec [10,859..11,665] 🟢 +3.3%
getOrInsert 3,471 ops/sec [3,449..3,513] → 2,262 ops/sec [2,243..2,285] 🔴 -34.8% 4,306 ops/sec [4,290..4,332] → 4,351 ops/sec [4,292..4,403] ~ overlap (+1.0%)
getOrInsertComputed 1,374 ops/sec [1,367..1,464] → 1,448 ops/sec [1,436..1,454] ~ overlap (+5.4%) 2,153 ops/sec [2,135..2,190] → 2,248 ops/sec [2,187..2,284] ~ overlap (+4.4%)
forced gc live-key retention 906 ops/sec [829..954] → 982 ops/sec [691..995] ~ overlap (+8.4%) 1,423 ops/sec [1,051..2,243] → 1,035 ops/sec [899..1,312] ~ overlap (-27.2%)
constructor from 50 values 9,117 ops/sec [8,979..9,336] → 9,326 ops/sec [9,126..15,294] ~ overlap (+2.3%) 13,722 ops/sec [13,655..14,003] → 23,031 ops/sec [19,268..23,104] 🟢 +67.8%
add 50 object values 2,621 ops/sec [2,597..2,633] → 2,983 ops/sec [2,665..4,435] 🟢 +13.8% 8,160 ops/sec [8,068..8,250] → 8,201 ops/sec [4,831..8,357] ~ overlap (+0.5%)
has checks (50 values) 74,631 ops/sec [45,960..77,365] → 77,852 ops/sec [77,546..78,005] 🟢 +4.3% 215,430 ops/sec [214,660..217,072] → 213,584 ops/sec [209,678..214,449] 🔴 -0.9%
delete values 11,989 ops/sec [11,902..12,069] → 12,214 ops/sec [12,078..12,245] 🟢 +1.9% 19,981 ops/sec [18,748..20,187] → 20,011 ops/sec [19,864..20,767] ~ overlap (+0.1%)
non-registered symbol values 9,586 ops/sec [9,549..9,682] → 9,878 ops/sec [9,817..9,986] 🟢 +3.0% 11,232 ops/sec [11,206..11,282] → 18,890 ops/sec [18,760..19,086] 🟢 +68.2%
forced gc pruning smoke 1,739 ops/sec [1,732..1,744] → 1,655 ops/sec [1,641..1,787] ~ overlap (-4.9%) 1,215 ops/sec [1,026..1,529] → 2,233 ops/sec [2,231..2,238] 🟢 +83.7%

Deterministic profile diff

closures

  • 🔴 OP_JUMP_IF_NUM_NOT_LTE_IMM: 0 → 51 (NEW)
  • 🔴 OP_CALL_SELF_NUM: 0 → 50 (NEW)
  • 🔴 OP_SUB_NUM_IMM: 0 → 50 (NEW)
  • 🔴 OP_LTE: 51 → 0 (REMOVED)
  • 🔴 OP_SUB: 50 → 0 (REMOVED)
  • 🔴 OP_LOAD_INT: 155 → 54 (-65.2%)
  • Total instructions: 1,309 → 1,107 (-15.4%)

fibonacci

  • 🔴 OP_JUMP_IF_NUM_NOT_LTE_IMM: 0 → 47,728 (NEW)
  • 🔴 OP_CALL_SELF_NUM: 0 → 47,724 (NEW)
  • 🔴 OP_SUB_NUM_IMM: 0 → 47,724 (NEW)
  • 🔴 OP_LTE: 47,728 → 0 (REMOVED)
  • 🔴 OP_SUB: 47,724 → 0 (REMOVED)
  • 🔴 OP_LOAD_INT: 95,571 → 119 (-99.9%)
  • 🔴 OP_JUMP_IF_FALSE: 47,749 → 21 (-100.0%)
  • 🔴 OP_CALL: 47,729 → 5 (-100.0%)
  • 🔴 OP_GET_UPVALUE: 48,005 → 281 (-99.4%)
  • 🔴 OP_MOVE: 24,006 → 144 (-99.4%)
  • Total instructions: 574,700 → 359,934 (-37.4%)

float16array

  • 🔴 OP_SUB_NUM_IMM: 0 → 200 (NEW)
  • 🔴 OP_SUB_FLOAT: 200 → 0 (REMOVED)
  • 🔴 OP_LOAD_INT: 953 → 753 (-21.0%)

typed-arrays

  • 🔴 OP_SUB_NUM_IMM: 0 → 100 (NEW)
  • 🔴 OP_SUB_FLOAT: 100 → 0 (REMOVED)

Measured on ubuntu-latest x64. Each PR run also builds the main base and benchmarks it back-to-back on the same runner after a warm-up discard, so the ranges compare two runs measured under the same conditions; overlapping min/max ranges are treated as unchanged noise. Percentage deltas are secondary context. See docs/adr/0076.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

JetStream 3 Performance Barometer

Workload Status Goccia main Goccia PR QuickJS Node.js vs QuickJS vs Node.js
hash-map pass 0.58 0.56 13.23 338.33 23.67× 605.22×
ai-astar pass 2.00 2.00 58.60 416.24 29.36× 208.57×
gaussian-blur pass 0.44 0.45 11.22 297.30 24.95× 661.31×
raytrace-public-class-fields pass 0.40 0.40 11.11 198.77 27.53× 492.42×
sync-fs pass 0.90 0.85 26.46 218.75 31.26× 258.45×
lazy-collections pass 1.92 2.01 68.06 150.68 33.93× 75.11×

Geomean reference ratio: QuickJS 28.23×; Node.js 304.55×.

1.00× means aligned; values above 1.00× mean Goccia was proportionally slower after normalizing JetStream’s higher-is-better score. This is a directional barometer across runtimes with different goals, not a product ranking. Raw samples and failure details remain in the jetstream-report artifact.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

AWFY Results

Target Status Goccia main Goccia PR QuickJS 2026-06-04 NodeJS v26.5.0 Δ PR vs main
Bounce pass 22.29ms 22.72ms 1.08ms 1.09ms ~ overlap (-1.92%)
CD pass 198.51ms 201.56ms 9.94ms 9.21ms ~ overlap (-1.54%)
DeltaBlue pass 4.57ms 4.69ms 298.65µs 1.63ms 🔴 -2.58%
Havlak pass 79.18s 80.03s 4269.51ms 190.12ms 🔴 -1.08%
Json pass 334.55ms 340.85ms 14.02ms 4.34ms ~ overlap (-1.88%)
List pass 15.13ms 15.39ms 1.00ms 0.76ms 🔴 -1.69%
Mandelbrot pass 31.78µs 33.08µs 5.95µs 91.07µs ~ overlap (-4.09%)
NBody pass 384.70µs 401.21µs 31.86µs 356.74µs ~ overlap (-4.29%)
Permute pass 41.19ms 41.73ms 1.85ms 0.80ms ~ overlap (-1.31%)
Queens pass 21.62ms 21.99ms 1.30ms 1.11ms ~ overlap (-1.72%)
Richards pass 897.18ms 911.64ms 51.87ms 6.33ms 🔴 -1.61%
Sieve pass 13.85ms 12.85ms 0.58ms 0.53ms 🟢 +7.26%
Storage pass 34.02ms 33.55ms 3.07ms 1.03ms ~ overlap (+1.38%)
Towers pass 60.08ms 60.44ms 3.06ms 1.15ms 🔴 -0.60%

Geomean Ratios

Ratio (row / column) Goccia main Goccia PR QuickJS 2026-06-04 NodeJS v26.5.0
Goccia main 1.000 0.989 16.261 20.218
Goccia PR 1.011 1.000 16.437 20.437
QuickJS 2026-06-04 0.061 0.061 1.000 1.243
NodeJS v26.5.0 0.049 0.049 0.804 1.000

14 pinned AWFY benchmarks. Medians from 5 interleaved samples per engine; raw JSON includes min/max/CV and is attached as the awfy-report artifact. Δ compares PR Goccia median against the same-runner main Goccia median; overlapping min/max ranges are treated as unchanged noise. Rows below 0.5ms are timer-floor sensitive.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

test262 Conformance

14 timeout(s) — counted separately from ordinary conformance failures; inspect the full artifact for affected tests.

Category Run Passed Δ Pass Failed Timeouts Δ Timeout Wrap-Infra Pass-rate Δ Rate
built-ins 23,668 23,668 ±0 0 0 ±0 0 100.0% ±0pp
harness 116 116 ±0 0 0 ±0 0 100.0% ±0pp
intl402 3,349 3,340 ±0 8 1 ±0 0 99.7% ±0pp
language 23,713 23,710 ±0 1 2 ±0 0 100.0% ±0pp
staging 1,482 1,385 +1 86 11 -1 0 93.5% +0.1pp
total 52,328 52,219 +1 95 14 -1 0 99.8% ±0pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
language/expressions 100.0% ±0pp 11,101 / 11,102
intl402/Temporal 100.0% ±0pp 2,028 / 2,029
intl402/NumberFormat 99.6% ±0pp 248 / 249
Per-test deltas (+0 / -0 / timeout +0 / -1)

Resolved timeouts (1):

  • staging/sm/extensions/recursion.js

Steady-state failures and timeouts are non-blocking; PASS → non-timeout failure transitions fail the conformance gate. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached main baseline.

@frostney frostney changed the title perf(bytecode): fuse proven numeric operations perf(bytecode): specialize proven numeric recursion Jul 21, 2026
@frostney
frostney marked this pull request as ready for review July 21, 2026 07:32
@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation internal Refactoring, CI, tooling, cleanup performance Performance improvement labels Jul 21, 2026
@frostney
frostney merged commit 0b76f51 into main Jul 21, 2026
49 checks passed
@frostney
frostney deleted the codex/numeric-superinstructions branch July 21, 2026 11:43
@frostney frostney mentioned this pull request Jul 21, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation internal Refactoring, CI, tooling, cleanup performance Performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant