Skip to content

feat(gc): add WeakRef and FinalizationRegistry#702

Merged
frostney merged 3 commits into
mainfrom
add-weakref-finalization-registry
Jun 3, 2026
Merged

feat(gc): add WeakRef and FinalizationRegistry#702
frostney merged 3 commits into
mainfrom
add-weakref-finalization-registry

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Jun 3, 2026

Summary

  • Implement WeakRef and FinalizationRegistry with weak target handling, kept objects, unregister tokens, and cleanup jobs.
  • Integrate weak processing with GC, queued roots, runtime idle/microtask checkpoints, and explicit worker-safe Goccia.gc().
  • Surface queueMicrotask and FinalizationRegistry cleanup callback errors, reject WeakRef/FinalizationRegistry from structuredClone, and update docs.

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

Verification run:

  • ./fixtures/ffi/build.sh
  • ./build.pas testrunner
  • ./build.pas loader
  • ./build/GocciaTestRunner tests
  • ./build/GocciaTestRunner tests --mode=bytecode
  • ./format.pas --check
  • git diff --check
  • Loader smoke checks for queueMicrotask and FinalizationRegistry cleanup callback error surfacing

Implement weak targets, kept objects, finalization cleanup jobs, and error surfacing for queueMicrotask/finalizers. Add JavaScript coverage across interpreter and bytecode behavior plus documentation updates.
@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 10:03am

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: 86ed69db-4b9a-4cf9-8116-0edf041f38ba

📥 Commits

Reviewing files that changed from the base of the PR and between 946cbe1 and 05cdd29.

📒 Files selected for processing (1)
  • source/units/Goccia.MicrotaskQueue.pas

📝 Walkthrough

Walkthrough

This pull request implements ES2021 WeakRef and FinalizationRegistry support and the GC/execution model changes required to support them: queued roots and kept objects in the collector, serialized collection, a dual microtask/finalization queue with queued-root lifecycle, new native WeakRef/FinalizationRegistry types and class-values, engine registration, structuredClone updates, and extensive tests.

Changes

WeakRef and FinalizationRegistry (ES2021)

Layer / File(s) Summary
Documentation and constructor constants
docs/built-ins.md, docs/garbage-collector.md, docs/interpreter.md, docs/language-tables.md, docs/language.md, docs/value-system.md, source/units/Goccia.Constants.ConstructorNames.pas, source/app/GocciaTestRunner.dpr
Documentation updated across language/GC/interpreter specs to describe WeakRef target eligibility, deref() stability, FinalizationRegistry registration/unregistration, cleanup scheduling, kept-object windows, and collection locking. Constructor name constants added.
Garbage collector root and kept-object management
source/units/Goccia.GarbageCollector.pas
TGarbageCollector adds queued-root ref-counting map and kept-object set. Collect and CollectYoung serialized via global critical section. Root marking includes queued and kept sources. Thread-local GC mark initialization avoids zero values.
Microtask queue finalization and root tracking
source/units/Goccia.MicrotaskQueue.pas, source/units/Goccia.FetchManager.pas
Dual-queue model: normal tasks and separate finalization cleanup queue. Queued-root lifecycle refactored into helpers. Task execution centralized with GC temp-root and kept-object clearing per task. EnqueueFinalizationCleanup public API. FetchManager clears kept objects around drain loops.
Promise and NativeFunction rooting for GC safety
source/units/Goccia.Values.NativeFunction.pas, source/units/Goccia.Builtins.GlobalPromise.pas, source/units/Goccia.Values.PromiseValue.pas
TGocciaNativeFunctionValue adds CapturedRoot and marking override. Promise resolve/reject native functions capture the created promise to anchor it during executor/thenable use.
WeakRef value type and prototype
source/units/Goccia.Values.WeakRefValue.pas
TGocciaWeakRefValue models ES2021 weak references with optional kept-object registration; realm-owned prototype exposes deref and Symbol.toStringTag; GC hooks handle target sweeping and deref stability per job.
FinalizationRegistry value type and cleanup scheduling
source/units/Goccia.Values.FinalizationRegistryValue.pas
TGocciaFinalizationRegistryValue manages registration cells with weak targets and held values; validates callable cleanup callback; implements register/unregister; enqueues cleanup microtasks during GC sweep; marks held values during marking.
Engine registration and class values
source/units/Goccia.Engine.pas, source/units/Goccia.Values.ClassValue.pas
Engine registers WeakRef and FinalizationRegistry constructors with prototype exposure and TypeDef metadata. WaitForRuntimeIdle clears kept objects at job boundaries. GocciaGC runs collect when instance exists. Class-value units add constructors.
Error handling and validation
source/units/Goccia.Error.Messages.pas, source/units/Goccia.Error.Suggestions.pas
New resource strings and suggestion messages for WeakRef/FinalizationRegistry runtime validation (deref receiver, cleanup callable, register/unregister usage, same-value rejection).
Global function updates
source/units/Goccia.Builtins.Globals.pas, source/units/Goccia.FetchManager.pas, source/units/Goccia.Threading.pas
Goccia.Builtins.Globals.pas adds value-unit uses, removes temporary microtask callback rooting, and extends structuredClone to reject WeakRef/FinalizationRegistry. FetchManager coordinates kept-object clearing; threading comment clarified.
Comprehensive test coverage
tests/built-ins/WeakRef/*, tests/built-ins/FinalizationRegistry/*, tests/built-ins/Object/prototype/toString.js, tests/built-ins/structuredClone/collections.js, tests/built-ins/global-properties/global-this.js, tests/language/classes/class-length-property.js
Test suites verify constructors, API validation, prototype shape, GC/finalization ordering and delivery, structuredClone rejection, Object.prototype.toString tags, subclassing, and globalThis exposure.

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly Related PRs

Suggested labels

documentation

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(gc): add WeakRef and FinalizationRegistry' directly and clearly summarizes the main feature being added in this changeset.
Description check ✅ Passed The PR description covers the main objectives (WeakRef/FinalizationRegistry implementation, GC integration, error surfacing), includes testing completion checkboxes with most checked, references verification steps, and aligns with the template structure.
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,965 passed; bytecode: 9,965 passed)
Metric Interpreted Bytecode
Total 9965 9965
Passed 9965 ✅ 9965 ✅
Workers 4 4
Test Duration 5.11s 5.71s
Lex (cumulative) 416.2ms 435.7ms
Parse (cumulative) 299.3ms 318.9ms
Compile (cumulative) 599.3ms
Execute (cumulative) 11.67s 13.10s
Engine Total (cumulative) 12.39s 14.45s
Lex (avg/worker) 104.1ms 108.9ms
Parse (avg/worker) 74.8ms 79.7ms
Compile (avg/worker) 149.8ms
Execute (avg/worker) 2.92s 3.27s
Engine Total (avg/worker) 3.10s 3.61s

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 212.10 MiB 208.58 MiB
GC Peak Live 238.48 MiB 236.41 MiB
GC Allocated During Run 310.45 MiB 302.79 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 100 100
GC Collected Objects 862,944 840,012
Heap Start Allocated 163.6 KiB 163.6 KiB
Heap End Allocated 1.55 MiB 1.55 MiB
Heap Delta Allocated 1.39 MiB 1.39 MiB
Heap Delta Free 432.9 KiB 432.9 KiB
Benchmarks (interpreted: 407; bytecode: 407)
Metric Interpreted Bytecode
Total 407 407
Workers 4 4
Duration 2.89min 2.66min

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.18 MiB 4.18 MiB
GC Peak Live 137.76 MiB 101.72 MiB
GC Allocated During Run 18.86 GiB 11.29 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 3,235 3,068
GC Collected Objects 300,813,827 256,066,908
Heap Start Allocated 1.28 MiB 1.28 MiB
Heap End Allocated 1.28 MiB 1.28 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: 🟢 352 improved · 🔴 13 regressed · 42 unchanged · avg +12.5%
Bytecode: 🟢 321 improved · 🔴 17 regressed · 69 unchanged · avg +7.9%

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

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.

Avoid retaining stale weak unregister-token pointers in FinalizationRegistry cells after GC. Keep the target cell alive for later cleanup and add regression coverage for unregister after token collection.
@frostney frostney marked this pull request as ready for review June 3, 2026 09:23
@coderabbitai coderabbitai Bot added new feature New feature or request spec compliance Mismatch against official JavaScript/TypeScript specification internal Refactoring, CI, tooling, cleanup labels Jun 3, 2026
@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,314 +77 7,130 69.6% +0.3pp
harness 116 72 ±0 44 62.1% ±0pp
intl402 3,324 1,000 ±0 2,324 30.1% ±0pp
language 23,635 14,679 +2 8,956 62.1% ±0pp
staging 1,484 579 ±0 903 39.0% ±0pp
total 52,008 32,644 +79 19,357 62.8% +0.2pp

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 (+79 / -0)

Newly passing (79):

  • built-ins/FinalizationRegistry/constructor.js
  • built-ins/FinalizationRegistry/instance-extensible.js
  • built-ins/FinalizationRegistry/is-a-constructor.js
  • built-ins/FinalizationRegistry/length.js
  • built-ins/FinalizationRegistry/name.js
  • built-ins/FinalizationRegistry/prop-desc.js
  • built-ins/FinalizationRegistry/proto.js
  • built-ins/FinalizationRegistry/prototype-from-newtarget-abrupt.js
  • built-ins/FinalizationRegistry/prototype-from-newtarget-custom.js
  • built-ins/FinalizationRegistry/prototype-from-newtarget.js
  • built-ins/FinalizationRegistry/prototype/constructor.js
  • built-ins/FinalizationRegistry/prototype/prop-desc.js
  • built-ins/FinalizationRegistry/prototype/proto.js
  • built-ins/FinalizationRegistry/prototype/register/custom-this.js
  • built-ins/FinalizationRegistry/prototype/register/heldValue-same-as-target.js
  • built-ins/FinalizationRegistry/prototype/register/holdings-any-value-type.js
  • built-ins/FinalizationRegistry/prototype/register/length.js
  • built-ins/FinalizationRegistry/prototype/register/name.js
  • built-ins/FinalizationRegistry/prototype/register/not-a-constructor.js
  • built-ins/FinalizationRegistry/prototype/register/prop-desc.js
  • built-ins/FinalizationRegistry/prototype/register/return-undefined-register-itself.js
  • built-ins/FinalizationRegistry/prototype/register/return-undefined-register-object.js
  • built-ins/FinalizationRegistry/prototype/register/return-undefined-register-symbol.js
  • built-ins/FinalizationRegistry/prototype/register/this-does-not-have-internal-target-throws.js
  • built-ins/FinalizationRegistry/prototype/register/this-not-object-throws.js
  • built-ins/FinalizationRegistry/prototype/register/throws-when-target-cannot-be-held-weakly.js
  • built-ins/FinalizationRegistry/prototype/register/throws-when-unregisterToken-not-undefined-and-cannot-be-held-weakly.js
  • built-ins/FinalizationRegistry/prototype/register/unregisterToken-same-as-holdings-and-target.js
  • built-ins/FinalizationRegistry/prototype/register/unregisterToken-same-as-holdings.js
  • built-ins/FinalizationRegistry/prototype/register/unregisterToken-same-as-target.js
  • built-ins/FinalizationRegistry/prototype/Symbol.toStringTag.js
  • built-ins/FinalizationRegistry/prototype/unregister/custom-this.js
  • built-ins/FinalizationRegistry/prototype/unregister/length.js
  • built-ins/FinalizationRegistry/prototype/unregister/name.js
  • built-ins/FinalizationRegistry/prototype/unregister/not-a-constructor.js
  • built-ins/FinalizationRegistry/prototype/unregister/prop-desc.js
  • built-ins/FinalizationRegistry/prototype/unregister/this-does-not-have-internal-cells-throws.js
  • built-ins/FinalizationRegistry/prototype/unregister/this-not-object-throws.js
  • built-ins/FinalizationRegistry/prototype/unregister/throws-when-unregisterToken-cannot-be-held-weakly.js
  • built-ins/FinalizationRegistry/prototype/unregister/unregister-object-token.js
  • built-ins/FinalizationRegistry/prototype/unregister/unregister-symbol-token.js
  • built-ins/FinalizationRegistry/returns-new-object-from-constructor.js
  • built-ins/FinalizationRegistry/target-not-callable-throws.js
  • built-ins/FinalizationRegistry/undefined-newtarget-throws.js
  • built-ins/FinalizationRegistry/unnaffected-by-poisoned-cleanupCallback.js
  • built-ins/Map/valid-keys.js
  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js
  • built-ins/Object/seal/seal-finalizationregistry.js
  • built-ins/Object/seal/seal-weakref.js
  • built-ins/Set/valid-values.js
  • built-ins/WeakRef/constructor.js
  • built-ins/WeakRef/instance-extensible.js
  • built-ins/WeakRef/is-a-constructor.js
  • built-ins/WeakRef/length.js
  • built-ins/WeakRef/name.js
  • built-ins/WeakRef/prop-desc.js
  • built-ins/WeakRef/proto.js
  • built-ins/WeakRef/prototype-from-newtarget-abrupt.js
  • built-ins/WeakRef/prototype-from-newtarget-custom.js
  • built-ins/WeakRef/prototype-from-newtarget.js
  • built-ins/WeakRef/prototype/constructor.js
  • built-ins/WeakRef/prototype/deref/custom-this.js
  • built-ins/WeakRef/prototype/deref/length.js
  • built-ins/WeakRef/prototype/deref/name.js
  • built-ins/WeakRef/prototype/deref/not-a-constructor.js
  • built-ins/WeakRef/prototype/deref/prop-desc.js
  • built-ins/WeakRef/prototype/deref/return-object-target.js
  • built-ins/WeakRef/prototype/deref/return-symbol-target.js
  • built-ins/WeakRef/prototype/deref/this-does-not-have-internal-target-throws.js
  • built-ins/WeakRef/prototype/deref/this-not-object-throws.js
  • built-ins/WeakRef/prototype/prop-desc.js
  • built-ins/WeakRef/prototype/proto.js
  • built-ins/WeakRef/prototype/Symbol.toStringTag.js
  • built-ins/WeakRef/returns-new-object-from-constructor-with-object-target.js
  • built-ins/WeakRef/returns-new-object-from-constructor-with-symbol-target.js
  • built-ins/WeakRef/throws-when-target-cannot-be-held-weakly.js
  • built-ins/WeakRef/undefined-newtarget-throws.js
  • language/expressions/class/subclass-builtins/subclass-WeakRef.js
  • language/statements/class/subclass-builtins/subclass-WeakRef.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.

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: 1

🤖 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.MicrotaskQueue.pas`:
- Around line 150-208: Remove the transient re-rooting in the task execution
path: delete the calls to TGarbageCollector.Instance.AddTempRoot for
ATask.Handler, ATask.Value and Promise at the start of the shown block and
remove the matching TGarbageCollector.Instance.RemoveTempRoot calls in the
finally; these objects are already rooted by AddQueuedRoots/RemoveQueuedRoots
(used by DrainQueue) so the extra AddTempRoot/RemoveTempRoot pairs (which use
set-membership, not ref-counting) must be eliminated to avoid accidentally
clearing an outer root.
🪄 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: f78980d2-c29a-42a2-8f2f-a7c59404382c

📥 Commits

Reviewing files that changed from the base of the PR and between 66694cd and 946cbe1.

📒 Files selected for processing (37)
  • docs/built-ins.md
  • docs/garbage-collector.md
  • docs/interpreter.md
  • docs/language-tables.md
  • docs/language.md
  • docs/value-system.md
  • source/app/GocciaTestRunner.dpr
  • source/units/Goccia.Builtins.GlobalPromise.pas
  • source/units/Goccia.Builtins.Globals.pas
  • source/units/Goccia.Constants.ConstructorNames.pas
  • source/units/Goccia.Engine.pas
  • source/units/Goccia.Error.Messages.pas
  • source/units/Goccia.Error.Suggestions.pas
  • source/units/Goccia.FetchManager.pas
  • source/units/Goccia.GarbageCollector.pas
  • source/units/Goccia.MicrotaskQueue.pas
  • source/units/Goccia.Threading.pas
  • source/units/Goccia.Values.ClassValue.pas
  • source/units/Goccia.Values.FinalizationRegistryValue.pas
  • source/units/Goccia.Values.NativeFunction.pas
  • source/units/Goccia.Values.PromiseValue.pas
  • source/units/Goccia.Values.WeakRefValue.pas
  • tests/built-ins/FinalizationRegistry/constructor.js
  • tests/built-ins/FinalizationRegistry/gc.js
  • tests/built-ins/FinalizationRegistry/prototype/register.js
  • tests/built-ins/FinalizationRegistry/prototype/toStringTag.js
  • tests/built-ins/FinalizationRegistry/prototype/unregister.js
  • tests/built-ins/FinalizationRegistry/subclassing.js
  • tests/built-ins/Object/prototype/toString.js
  • tests/built-ins/WeakRef/constructor.js
  • tests/built-ins/WeakRef/gc.js
  • tests/built-ins/WeakRef/prototype/deref.js
  • tests/built-ins/WeakRef/prototype/toStringTag.js
  • tests/built-ins/WeakRef/subclassing.js
  • tests/built-ins/global-properties/global-this.js
  • tests/built-ins/structuredClone/collections.js
  • tests/language/classes/class-length-property.js

Comment thread source/units/Goccia.MicrotaskQueue.pas Outdated
@coderabbitai coderabbitai Bot added the documentation Improvements or additions to documentation label Jun 3, 2026
@frostney frostney merged commit a658c02 into main Jun 3, 2026
14 checks passed
@frostney frostney deleted the add-weakref-finalization-registry branch June 3, 2026 14:49
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