Skip to content

Implement ECMAScript realm execution contexts#703

Merged
frostney merged 5 commits into
mainfrom
codex/es-realms
Jun 3, 2026
Merged

Implement ECMAScript realm execution contexts#703
frostney merged 5 commits into
mainfrom
codex/es-realms

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Jun 3, 2026

Summary

  • Implement ECMA-262-style realm execution context tracking across interpreter and bytecode execution.
  • Move tagged template object caching into realm-owned template maps with stable AST/bytecode template-site identifiers.
  • Add repeated engine execution coverage at native and CLI/REPL layers, including interpreted and bytecode modes.
  • Adjust the interpreter stack-depth guard to keep overflow behavior as JavaScript RangeError instead of native stack failure.

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

Commands run:

  • ./build.pas clean testrunner loader repl bundler benchmarkrunner loaderbare tests
  • ./build.pas clean tests testrunner
  • ./build/Goccia.Realm.Test
  • ./build/Goccia.Engine.Realm.Test
  • ./build/GocciaTestRunner tests --no-progress
  • ./build/GocciaTestRunner tests --no-progress --mode=bytecode
  • bun run scripts/test-cli-apps.ts
  • bun run scripts/test-cli.ts
  • ./format.pas --check
  • git diff --check

frostney added 2 commits June 3, 2026 12:44
Add explicit realm and execution-context plumbing across interpreter and bytecode execution, move tagged template caching into realm-owned template maps, and cover repeated engine execution in CLI and native tests.

Verification:
- ./build/Goccia.Engine.Realm.Test
- ./build/GocciaTestRunner tests --no-progress
- ./build/GocciaTestRunner tests --no-progress --mode=bytecode
- bun run scripts/test-cli-apps.ts
- bun run scripts/test-cli.ts
- ./format.pas --check
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 3, 2026

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 Jun 3, 2026 5:58pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 3, 2026

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

Run ID: c5aa56ea-14d3-4b1d-b88f-cba52b6e3abf

📥 Commits

Reviewing files that changed from the base of the PR and between d742935 and b70bf8b.

📒 Files selected for processing (5)
  • source/units/Goccia.Engine.pas
  • source/units/Goccia.ExecutionContext.pas
  • source/units/Goccia.Executor.Bytecode.pas
  • source/units/Goccia.Realm.Test.pas
  • source/units/Goccia.VM.pas
🚧 Files skipped from review as they are similar to previous changes (3)
  • source/units/Goccia.ExecutionContext.pas
  • source/units/Goccia.Engine.pas
  • source/units/Goccia.VM.pas

📝 Walkthrough

Walkthrough

This PR centralizes realm ownership and ECMA-262-style execution contexts: introduces TGocciaExecutionContext/stack and RAII scopes, expands TGocciaRealm to own intrinsics/global/env/loaded-module/template maps, adds template-site IDs and realm-scoped template caching, wires realm propagation through engine/interpreter/executor/VM/frame lifecycles, updates tests/docs, and lowers default stack depth.

Changes

Realm Isolation and Execution Context Integration

Layer / File(s) Summary
Template Site ID Infrastructure
source/units/Goccia.AST.Expressions.pas, source/units/Goccia.Bytecode.Chunk.pas
Thread-safe global allocators assign unique TemplateSiteId to TGocciaTaggedTemplateExpression and TGocciaFunctionTemplate during construction, enabling template object keying across executions.
Execution Context Stack Unit
source/units/Goccia.ExecutionContext.pas
New unit defines TGocciaExecutionContext record (realm/scope/function/source), thread-local TGocciaExecutionContextStack managing push/pop/current-realm queries, and TGocciaExecutionContextScope RAII wrapper for safe context lifecycle.
Realm Record Expansion and Template Ownership
source/units/Goccia.Realm.pas
TGocciaRealm now owns intrinsics, global object/env, host-defined payload, template-object map, and per-realm function execution context stack with APIs for template management, host finalization, and agent signifiers.
Engine and Executor Realm Initialization
source/units/Goccia.Engine.pas, source/units/Goccia.Executor.pas, source/units/Goccia.Executor.Bytecode.pas, source/units/Goccia.Executor.Interpreter.pas
Engine creates per-engine realm on startup with execution context scope; executors initialize and expose realm; bytecode executor conditionally switches VM realm during module evaluation.
Interpreter and Module Loader Execution Context Integration
source/units/Goccia.Interpreter.pas, source/units/Goccia.Modules.Loader.pas, source/units/Goccia.Evaluator.Context.pas
Interpreter Execute and EvaluateModuleBody wrap execution in execution context scopes; module loader wires realm into evaluation context; TGocciaEvaluationContext now includes Realm.
VM and Closure Execution Context Management
source/units/Goccia.VM.pas, source/units/Goccia.VM.CallFrame.pas, source/units/Goccia.VM.Closure.pas
VM tracks execution-context-pushed state per frame; SetupNewFrame conditionally pushes contexts when realm is assigned; ExecuteModule/ExecuteFunction manage top-level context lifecycles; closures carry function value for function-context pushes.
Evaluator and Realm-Aware Template Object Caching
source/units/Goccia.Evaluator.pas
Evaluator computes TemplateKey from TemplateSiteId and prefers realm-level cached template objects (GetTemplateObject/SetTemplateObject) when AContext.Realm is present; falls back to node-local cache otherwise.
Function and Generator Execution Context Tracking
source/units/Goccia.Values.FunctionValue.pas, source/units/Goccia.Values.GeneratorValue.pas
Function/generator invocation initializes evaluation context with CurrentRealm, pushes/pops current function execution context around body execution, and guards pop with a boolean when push occurred.
Call Stack Depth Limit Adjustment
source/units/Goccia.StackLimit.pas, source/units/Goccia.Evaluator.pas, tests/language/functions/stack-depth-limit.js
Default DEFAULT_MAX_STACK_DEPTH reduced from 3500 to 2900; CheckStackDepth calls are guarded with Assigned(TGocciaCallStack.Instance) to avoid nil dereference; tests updated accordingly.
Tests and REPL Regression
source/units/Goccia.Realm.Test.pas, source/units/Goccia.Engine.Realm.Test.pas, scripts/test-cli-apps.ts
Added unit tests for realm fields, template map behavior, execution-context stack realm switching, engine-level interpreter/bytecode execution-context behavior, repeated-tagged-template engine runs; REPL regression test validates tagged-template call-site identity across modes.
Documentation and Glossary Updates
CONTEXT.md, docs/architecture.md, docs/build-system.md, docs/bytecode-vm.md, docs/core-patterns.md, docs/embedding.md
Glossary and docs redefined Realm as ECMAScript execution domain owning intrinsics/global/env/template maps, documented execution-context-driven realm switching, and updated stack-size default to 2900 everywhere.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature: ECMAScript realm execution contexts are implemented throughout the codebase with supporting infrastructure for template caching, execution context stacks, and realm ownership.
Description check ✅ Passed The description covers all required template sections: a clear summary of changes, links to related testing, documentation updates confirmation, and explicit command runs demonstrating thorough testing across interpreter, bytecode, native tests, and CLI tools.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

Suite Timing

Test Runner (interpreted: 9,985 passed; bytecode: 9,985 passed)
Metric Interpreted Bytecode
Total 9985 9985
Passed 9985 ✅ 9985 ✅
Workers 4 4
Test Duration 4.61s 6.22s
Lex (cumulative) 298.8ms 395.0ms
Parse (cumulative) 222.7ms 294.9ms
Compile (cumulative) 598.9ms
Execute (cumulative) 10.74s 13.90s
Engine Total (cumulative) 11.26s 15.19s
Lex (avg/worker) 74.7ms 98.8ms
Parse (avg/worker) 55.7ms 73.7ms
Compile (avg/worker) 149.7ms
Execute (avg/worker) 2.68s 3.48s
Engine Total (avg/worker) 2.82s 3.80s

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 214.95 MiB 211.76 MiB
GC Peak Live 230.97 MiB 240.46 MiB
GC Allocated During Run 315.37 MiB 308.03 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 100 100
GC Collected Objects 871,166 848,202
Heap Start Allocated 164.3 KiB 164.3 KiB
Heap End Allocated 1.62 MiB 1.62 MiB
Heap Delta Allocated 1.46 MiB 1.46 MiB
Heap Delta Free 742.3 KiB 742.3 KiB
Benchmarks (interpreted: 407; bytecode: 407)
Metric Interpreted Bytecode
Total 407 407
Workers 4 4
Duration 2.71min 2.55min

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 4.23 MiB 4.23 MiB
GC Peak Live 133.32 MiB 83.37 MiB
GC Allocated During Run 16.03 GiB 9.49 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 3,077 2,900
GC Collected Objects 255,306,489 212,708,480
Heap Start Allocated 1.35 MiB 1.35 MiB
Heap End Allocated 1.35 MiB 1.35 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 25 improved · 🔴 43 regressed · 339 unchanged · avg -0.1%
Bytecode: 🟢 22 improved · 🔴 167 regressed · 218 unchanged · avg -5.8%

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

Deterministic profile diff

Deterministic profile diff: no significant changes.

Measured on ubuntu-latest x64. Benchmark ranges compare cached main-branch min/max ops/sec with the PR run; overlapping ranges are treated as unchanged noise. Percentage deltas are secondary context.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 3, 2026

test262 Conformance

Category Run Passed Δ Pass Failed Pass-rate Δ Rate
built-ins 23,449 16,342 +1 7,102 69.7% ±0pp
harness 116 72 ±0 44 62.1% ±0pp
intl402 3,324 1,011 ±0 2,313 30.4% ±0pp
language 23,635 14,679 ±0 8,956 62.1% ±0pp
staging 1,484 581 ±0 901 39.2% ±0pp
total 52,008 32,685 +1 19,316 62.8% ±0pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
language/block-scope 99.3% ±0pp 144 / 145
built-ins/WeakMap 99.3% ±0pp 140 / 141
language/asi 99.0% ±0pp 101 / 102
Per-test deltas (+1 / -0)

Newly passing (1):

  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js

Steady-state failures are non-blocking; regressions vs the cached main baseline (lower total pass count, or any PASS → non-PASS transition) 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 marked this pull request as ready for review June 3, 2026 17:02
@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation new feature New feature or request spec compliance Mismatch against official JavaScript/TypeScript specification internal Refactoring, CI, tooling, cleanup labels Jun 3, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@source/units/Goccia.ExecutionContext.pas`:
- Around line 123-127: In TGocciaExecutionContextStack.Pop the code currently
zeroes the popped entry with FillChar on
GExecutionContextStack[GExecutionContextStackCount], which bypasses
managed-string finalization for the embedded TGocciaExecutionContext (which has
SourcePath: string); change the cleanup to a managed-safe operation by assigning
GExecutionContextStack[GExecutionContextStackCount] :=
Default(TGocciaExecutionContextStackEntry) (or call Finalize(...) then
Default(...)) instead of FillChar so SourcePath and other managed fields are
finalized properly; update the Pop implementation that references
GExecutionContextStack and GExecutionContextStackCount accordingly.

In `@source/units/Goccia.Executor.Bytecode.pas`:
- Around line 120-128: The code currently overwrites the VM realm on exit by
resetting FVM.Realm to FRealm; instead capture the prior realm before changing
it and restore that saved realm in the finally block. Specifically, save the
existing realm (e.g., SavedRealm := FVM.Realm) before assigning FVM.Realm :=
AContext.Realm in the try section, and in the finally block restore FVM.Realm :=
SavedRealm (leaving the existing FVM.GlobalScope save/restore using
SavedGlobalScope and the AContext.Scope handling unchanged). This ensures nested
ExecuteModule calls (SavedGlobalScope, AContext.Scope, AContext.Realm,
FVM.Realm) correctly restore the outer realm rather than forcing FRealm.

In `@source/units/Goccia.Realm.Test.pas`:
- Around line 378-405: The test resets the global CurrentRealm to nil in the
finally block which can clobber an existing thread realm; modify
TTestRealm.TestExecutionContextStackSetsCurrentRealm to capture the prior realm
into a local variable (e.g., PrevRealm) before calling
SetCurrentRealm(OuterRealm) and then in the finally restore it via
SetCurrentRealm(PrevRealm) instead of SetCurrentRealm(nil); keep the rest of the
teardown (freeing Guard, InnerRealm, OuterRealm) intact and ensure you reference
SetCurrentRealm, CurrentRealm, CreateExecutionContext and
RunningExecutionContext when making the change.

In `@source/units/Goccia.VM.pas`:
- Around line 7715-7720: The code pushes a new execution context using
FCurrentModuleSourcePath (caller module) causing source metadata to attribute to
the caller; change the source-file argument passed into CreateExecutionContext
to prefer the callee template's debug-info source: use
ATemplate.DebugInfo.SourceFile or AClosure.Template.DebugInfo.SourceFile when
available and only fall back to FCurrentModuleSourcePath if debug info is
missing; update the TGocciaExecutionContextStack.Push call in the
APushExecutionContext branch (and the similar block at the OP_IMPORT_META
location) to pass that resolved source-file string instead of
FCurrentModuleSourcePath so contexts reflect the defining module.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: df75f0cd-2eaa-47a4-a89d-a96777344fff

📥 Commits

Reviewing files that changed from the base of the PR and between 1f6871b and d742935.

📒 Files selected for processing (28)
  • CONTEXT.md
  • docs/architecture.md
  • docs/build-system.md
  • docs/bytecode-vm.md
  • docs/core-patterns.md
  • docs/embedding.md
  • scripts/test-cli-apps.ts
  • source/units/Goccia.AST.Expressions.pas
  • source/units/Goccia.Bytecode.Chunk.pas
  • source/units/Goccia.Engine.Realm.Test.pas
  • source/units/Goccia.Engine.pas
  • source/units/Goccia.Evaluator.Context.pas
  • source/units/Goccia.Evaluator.pas
  • source/units/Goccia.ExecutionContext.pas
  • source/units/Goccia.Executor.Bytecode.pas
  • source/units/Goccia.Executor.Interpreter.pas
  • source/units/Goccia.Executor.pas
  • source/units/Goccia.Interpreter.pas
  • source/units/Goccia.Modules.Loader.pas
  • source/units/Goccia.Realm.Test.pas
  • source/units/Goccia.Realm.pas
  • source/units/Goccia.StackLimit.pas
  • source/units/Goccia.VM.CallFrame.pas
  • source/units/Goccia.VM.Closure.pas
  • source/units/Goccia.VM.pas
  • source/units/Goccia.Values.FunctionValue.pas
  • source/units/Goccia.Values.GeneratorValue.pas
  • tests/language/functions/stack-depth-limit.js

Comment thread source/units/Goccia.ExecutionContext.pas Outdated
Comment thread source/units/Goccia.Executor.Bytecode.pas Outdated
Comment thread source/units/Goccia.Realm.Test.pas
Comment thread source/units/Goccia.VM.pas
frostney added 2 commits June 3, 2026 19:55
- clear execution-context stack records without FillChar on managed fields
- restore the previous bytecode VM realm after nested module execution
- restore prior CurrentRealm in realm stack tests
- attribute bytecode function contexts to callee debug source paths
@frostney frostney merged commit 41bb2e1 into main Jun 3, 2026
14 checks passed
@frostney frostney deleted the codex/es-realms branch June 3, 2026 19:02
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 new feature New feature or request spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant