Skip to content

Fix for-loop update closure environments#676

Merged
frostney merged 3 commits into
mainfrom
issue-539-for-update-closures
May 21, 2026
Merged

Fix for-loop update closure environments#676
frostney merged 3 commits into
mainfrom
issue-539-for-update-closures

Conversation

@frostney
Copy link
Copy Markdown
Owner

Summary

Testing

  • Verified no regressions and confirmed the new feature or bugfix in end-to-end JavaScript/TypeScript tests
    • ./build/GocciaTestRunner tests --asi --unsafe-ffi --no-progress
    • ./build/GocciaTestRunner tests --asi --unsafe-ffi --mode=bytecode --no-progress
    • ./build/GocciaTestRunner tests/language/for-loop/let-per-iteration.js --asi --unsafe-ffi --mode=bytecode
    • ./build/GocciaTestRunner tests/language/for-loop --asi --unsafe-ffi
    • ./build/GocciaTestRunner tests/language/for-loop --asi --unsafe-ffi --mode=bytecode
    • ./build/GocciaTestRunner tests/language/for-loop-var --asi --unsafe-ffi
    • ./build/GocciaTestRunner tests/language/for-loop-var --asi --unsafe-ffi --mode=bytecode
  • Updated documentation
    • Not needed; this fixes internal spec behavior for an existing compatibility feature and adds regression coverage.
  • 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

Additional checks:

  • ./format.pas --check
  • ./build.pas clean testrunner
  • ./build.pas bundler
  • printf '%s\n' 'const fns = []; for (let i = 0; i < 3; i++, fns.push(() => i)) {} fns.map(fn => fn());' | ./build/GocciaBundler --compat-traditional-for-loop --output=/tmp/issue539-update-closures.gbc

@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 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 May 20, 2026 10:36pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 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: 69255233-34c7-4935-96ea-a53e3a71b681

📥 Commits

Reviewing files that changed from the base of the PR and between 25df957 and e432237.

📒 Files selected for processing (4)
  • source/units/Goccia.Compiler.Statements.pas
  • tests/language/classes/class-expression-extends.js
  • tests/language/for-loop/strict-types/goccia.json
  • tests/language/for-loop/strict-types/per-iteration-type-metadata.js
✅ Files skipped from review due to trivial changes (1)
  • tests/language/for-loop/strict-types/goccia.json

📝 Walkthrough

Walkthrough

Restructures lexical for loop compilation and evaluation to create three per-iteration environments (outer/body/update), adds a compiler helper to copy per-iteration type metadata, extends generator for-loop state to track the update scope across yields, and adds tests for closure capture and strict-type per-iteration metadata.

Changes

For-Loop Update-Phase Scoping

Layer / File(s) Summary
Generator for-loop state contract
source/units/Goccia.Generator.Continuation.pas
TGocciaGeneratorForLoopState adds UpdateScope: TGocciaScope; constructor initializes it and marking includes it.
Compiler: local type metadata helper
source/units/Goccia.Compiler.Statements.pas
Adds CopyLocalTypeMetadata to copy type hints/strictness/annotations between local slots and update template slot flags when declaring iteration slots.
Compiler: three-scope for-loop generation
source/units/Goccia.Compiler.Statements.pas
Rewrites CompileForStatement lexical-init path to allocate OuterSlots, BodySlots, and UpdateSlots, maintain separate closed-upvalue arrays, compile condition in body scope, close body upvalues, compile update in fresh update scope, sync update-slot values back to outer slots, and patch loop exits.
Evaluator: lexical update phase and generator resume
source/units/Goccia.Evaluator.pas
EvaluateFor adds UpdateScope/UpdateContext, restores saved update scope when resuming at the update phase, creates a fresh per-iteration update scope after the body, evaluates the update expression there with type-hint propagation, and syncs modified bindings back to the header scope.
Test: closure capture in update/body/test expressions
tests/language/for-loop/let-per-iteration.js
New tests verify closures created in the update expression pin the post-body per-iteration binding, body vs update closures are distinct, continue interacts correctly with update closures, and test-expression closures capture the current body binding.
Test: strict-types per-iteration metadata
tests/language/for-loop/strict-types/goccia.json, tests/language/for-loop/strict-types/per-iteration-type-metadata.js
Adds feature flags and tests asserting per-iteration type annotations (condition/body/update) are preserved and enforced, expecting TypeError on invalid assignments.
Test: class expression extends dynamic value
tests/language/classes/class-expression-extends.js
Adds a test covering a class expression that extends a dynamic base, calls super(), sets an instance field, and checks instanceof and inherited behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • frostney/GocciaScript#644: Modifies generator for-loop resume state and loop-phase scoping; related changes to generator/evaluator resume behavior.
  • frostney/GocciaScript#633: Changes EvaluateFor and generator for-loop state handling for resume semantics; overlaps with update-phase scoping fixes.
  • frostney/GocciaScript#531: Earlier work on compat/traditional-for-loop and per-iteration environment model that this PR builds upon.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly summarizes the main change: fixing for-loop update closure environments to match ES2026 spec behavior.
Description check ✅ Passed Description includes all required sections: summary describing the change (distinct update environments), testing checklist with completed E2E tests and clear note on documentation not needed, and issue closure reference.
Linked Issues check ✅ Passed Changes implement all primary requirements from #539: two-scope-per-iteration model (HeaderScope, BodyIterScope, UpdateIterScope), separate upvalue closure for body/update scopes, environment preservation across generator resumes, and regression test coverage for closure pinning.
Out of Scope Changes check ✅ Passed All changes align with issue #539 scope: bytecode and evaluator updates for update environments, generator continuation updates for state tracking, and test additions for closure semantics. The class-expression test appears related to a secondary fix (#678) but is minimal and doesn't distract from primary objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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 May 20, 2026

Suite Timing

Test Runner (interpreted: 9,744 passed; bytecode: 9,744 passed)
Metric Interpreted Bytecode
Total 9744 9744
Passed 9744 ✅ 9744 ✅
Workers 4 4
Test Duration 3.11s 2.21s
Lex (cumulative) 428.3ms 224.9ms
Parse (cumulative) 297.6ms 214.8ms
Compile (cumulative) 469.5ms
Execute (cumulative) 3.15s 2.02s
Engine Total (cumulative) 3.88s 2.93s
Lex (avg/worker) 107.1ms 56.2ms
Parse (avg/worker) 74.4ms 53.7ms
Compile (avg/worker) 117.4ms
Execute (avg/worker) 787.7ms 504.4ms
Engine Total (avg/worker) 969.2ms 731.7ms

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 279.02 MiB 273.30 MiB
GC Peak Live 279.03 MiB 273.31 MiB
GC Allocated During Run 283.47 MiB 277.76 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 1 1
GC Collected Objects 88 88
Heap Start Allocated 157.9 KiB 157.9 KiB
Heap End Allocated 1.53 MiB 1.53 MiB
Heap Delta Allocated 1.38 MiB 1.38 MiB
Heap Delta Free 1.16 MiB 1.16 MiB
Benchmarks (interpreted: 407; bytecode: 407)
Metric Interpreted Bytecode
Total 407 407
Workers 4 4
Duration 2.41min 2.53min

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 3.93 MiB 3.92 MiB
GC Peak Live 96.42 MiB 87.96 MiB
GC Allocated During Run 13.62 GiB 11.12 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 2,812 2,674
GC Collected Objects 247,392,546 264,153,477
Heap Start Allocated 1.27 MiB 1.27 MiB
Heap End Allocated 1.27 MiB 1.27 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 21 improved · 🔴 331 regressed · 55 unchanged · avg -5.6%
Bytecode: 🟢 31 improved · 🔴 92 regressed · 284 unchanged · avg -0.4%

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

Deterministic profile diff

classes

  • 🔴 OP_CLOSE_UPVALUE: 0 → 1 (NEW)

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

test262 Conformance

Category Run Passed Δ Pass Failed Pass-rate Δ Rate
built-ins 23,449 16,067 +1 7,377 68.5% ±0pp
harness 116 72 ±0 44 62.1% ±0pp
intl402 3,324 892 ±0 2,432 26.8% ±0pp
language 23,635 14,205 +2 9,430 60.1% ±0pp
staging 1,484 571 ±0 910 38.5% ±0pp
total 52,008 31,807 +3 20,193 61.2% ±0pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
built-ins/WeakMap 99.3% ±0pp 140 / 141
built-ins/WeakSet 98.8% ±0pp 84 / 85
language/future-reserved-words 98.1% ±0pp 53 / 54
Per-test deltas (+3 / -0)

Newly passing (3):

  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js
  • language/statements/let/syntax/let-closure-inside-condition.js
  • language/statements/let/syntax/let-closure-inside-next-expression.js

Steady-state failures are non-blocking; regressions vs the cached main baseline (lower total pass count, or any PASS → non-PASS transition) fail the conformance gate. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached main baseline.

@frostney frostney marked this pull request as ready for review May 20, 2026 21:19
@coderabbitai coderabbitai Bot added bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification internal Refactoring, CI, tooling, cleanup labels May 20, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 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.Compiler.Statements.pas`:
- Around line 2557-2563: The synthetic per-iteration locals created in the loop
(PerIterNames -> BodySlots and later UpdateSlots) only copy register values but
not the original binding metadata, so type hints, strict flags and annotations
are lost; after each ACtx.Scope.DeclareLocal(Name, PerIterIsConst) call in the
PerIterNames loop (and the analogous loop at the 2592–2598 region), copy/clone
the source binding's metadata (type hint, strictness flag, annotation metadata)
from the original binding (the corresponding OuterSlots entry / source binding
object) onto the newly returned local slot (BodySlots[I] and UpdateSlots[I]) so
the synthetic locals carry the same metadata for proper typing and strict
enforcement. Ensure you do this immediately after DeclareLocal(...) for both
BodySlots and UpdateSlots.
🪄 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: fbf8af15-6660-4601-b34f-91c56c0b4937

📥 Commits

Reviewing files that changed from the base of the PR and between a1a0ad5 and 25df957.

📒 Files selected for processing (4)
  • source/units/Goccia.Compiler.Statements.pas
  • source/units/Goccia.Evaluator.pas
  • source/units/Goccia.Generator.Continuation.pas
  • tests/language/for-loop/let-per-iteration.js

Comment thread source/units/Goccia.Compiler.Statements.pas
frostney added 2 commits May 20, 2026 23:18
- Preserve strict type metadata on synthetic for-loop per-iteration locals.\n- Close anonymous class-expression super upvalues before freeing their register.\n- Add regression coverage for strict for-loop metadata and class-expression super construction.\n\nFixes #678.
@frostney frostney merged commit 314cdeb into main May 21, 2026
14 checks passed
@frostney frostney deleted the issue-539-for-update-closures branch May 21, 2026 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working internal Refactoring, CI, tooling, cleanup spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Engine: closures created inside for(;;) update pin wrong environment per ES2026 §14.7.4.4

1 participant