Skip to content

Fix microtask drain re-entrancy crashing async-generator yield rejection#465

Merged
frostney merged 2 commits intomainfrom
t3code/test262-filter-update
Apr 29, 2026
Merged

Fix microtask drain re-entrancy crashing async-generator yield rejection#465
frostney merged 2 commits intomainfrom
t3code/test262-filter-update

Conversation

@frostney
Copy link
Copy Markdown
Owner

Summary

  • Fixes a stack-overflow (SIGSEGV) in the bytecode VM when a microtask handler triggers a recursive DrainQueue — for example, an async generator that yields a rejected promise, where iter.next()'s rejection handler synchronously calls iter.next() again. The previous TGocciaMicrotaskQueue.DrainQueue kept already-processed tasks in the queue until the outermost drain's final FQueue.Clear, so any nested drain re-iterated from index 0 and re-ran every prior task. The fix pops each task with FQueue.Delete(0) before invoking it, so recursive drains only see remaining or newly-enqueued tasks.
  • Updates scripts/test262_syntax_filter.py to mark generators, async-generator, WeakMap, WeakSet, and symbols-as-weakmap-keys as supported features (shipped via Add generator and async generator support #432 and Implement WeakMap and WeakSet built-ins #437) and removes the syntax patterns and SKIP_PATH_SEGMENTS entries that previously hid those tests from the suite.
  • Adds JS regression tests covering both the underlying microtask-drain re-entrancy and the async-generator trigger patterns (yield Promise.reject(…), yield* of an iterable whose [Symbol.iterator] returns null, generator that throws synchronously, iter.next() from a rejection handler).

test262 baseline (bytecode, ASI + --compat-var/--compat-function/--unsafe-function-constructor)

Before After
Discovered 47,416 47,416
Eligible 39,025 (82.3%) 39,025 (82.3%)
Passed 19,470 (49.9%) 19,595 (50.2%)
Failed 18,896 19,430
Errors (bytecode crashes) 465 0
Timeouts 0 0
Duration 274s 156s

All 465 previously-crashing async-generator tests now run to completion. 253 of them pass; the rest fail cleanly with assertion errors (mostly spec-compliance gaps in AsyncGeneratorYield's rejection handling — separate work).

Test plan

  • ./build.pas testrunner loader — both binaries build clean
  • ./build/GocciaTestRunner tests --asi --unsafe-ffi --no-progress — 8195 / 8200 pass (5 pre-existing FFI fixture failures, unchanged)
  • New regression tests pass in both bytecode and interpreted modes
  • Manual repro (async function* () { yield Promise.reject(0); yield 1; } with iter.next().catch(() => iter.next())) no longer crashes the bytecode VM
  • Full test262 re-run confirms 465 → 0 crashes

🤖 Generated with Claude Code

TGocciaMicrotaskQueue.DrainQueue kept already-processed tasks in the
queue until a final FQueue.Clear at the outermost drain's exit. When a
microtask handler triggered a recursive drain — for example via
AwaitValue on a settled promise calling DrainMicrotasksAndFetchCompletions
— the inner drain re-iterated from index 0 and re-ran every prior task.

Async generators yielding a rejected promise (or yielding via yield* over
a non-iterable) hit this on every test262 run: iter.next() #1 awaited the
yielded rejection, the outer Promise rejected, the .catch handler fired
in the next drain, called iter.next() #2, which in turn drained
microtasks... until the call stack overflowed (SIGSEGV).

DrainQueue now pops each task with FQueue.Delete(0) before invoking it,
so recursive drains only see remaining or newly-enqueued tasks.

Also updates scripts/test262_syntax_filter.py to mark generators,
async-generator, WeakMap, WeakSet, and symbols-as-weakmap-keys as
supported (shipped in #432, #437) and removes the syntax patterns and
SKIP_PATH_SEGMENTS that previously hid those tests from the suite.

test262 (bytecode mode, ASI + compat-var/function/Function on):
  Eligible 39,025 / 47,416 — passes 19,470 → 19,595, errors 465 → 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 29, 2026

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

Project Deployment Actions Updated (UTC)
gocciascript-homepage Ready Ready Preview, Comment Apr 29, 2026 9:49pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 29, 2026

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: 3863a8f5-d0e4-4428-a5f5-d3ab9aab1c54

📥 Commits

Reviewing files that changed from the base of the PR and between cabf981 and 461d553.

📒 Files selected for processing (2)
  • source/units/Goccia.MicrotaskQueue.pas
  • tests/language/async-generators/yield-rejected-promise.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/language/async-generators/yield-rejected-promise.js

📝 Walkthrough

Walkthrough

Enables generator-related and WeakMap/WeakSet syntax in the test filter, rewrites the microtask queue drain to avoid reprocessing tasks during re-entrancy, and adds regression tests for microtask ordering and async-generator rejection/iteration edge cases.

Changes

Cohort / File(s) Summary
Syntax Filter Configuration
scripts/test262_syntax_filter.py
Marks generators, async-generator, async-generators, WeakMap, WeakSet, and symbols-as-weakmap-keys as supported; removes generator-related patterns from the always-unsupported regex; stops auto-skipping generator/weakmap/weakset test path segments.
Microtask Queue Implementation
source/units/Goccia.MicrotaskQueue.pas
Reworks DrainQueue to advance a head index before executing each microtask (prevents reprocessing on nested drains); introduces per-task GC temporary roots and per-task try/finally cleanup; updates ClearQueue and HasPending to honor the head index; replaces full-clear finally with conditional compaction.
Regression Tests
tests/built-ins/Promise/microtask-ordering.js, tests/language/async-generators/yield-rejected-promise.js
Adds microtask-ordering tests that validate nested-drain non-reentrance and no-duplicate delivery; adds async-generator tests for rejected-yield behavior, yield* delegation errors, and synchronous generator failure semantics.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

bug, spec compliance, internal

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically identifies the main fix: resolving a microtask drain re-entrancy issue that crashes when async generators yield rejected promises.
Description check ✅ Passed The description comprehensively covers the problem, solution, impacts (test262 metrics), and testing verification, meeting or exceeding all template requirements.
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.


Review rate limit: 4/5 reviews remaining, refill in 12 minutes.

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

@coderabbitai coderabbitai Bot added bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification internal Refactoring, CI, tooling, cleanup labels Apr 29, 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

🧹 Nitpick comments (1)
source/units/Goccia.MicrotaskQueue.pas (1)

104-109: Avoid Delete(0) on every microtask.

Line 109 shifts the entire TList on each iteration, so draining n microtasks becomes O(n²). That’s fine for landing the correctness fix, but Promise-heavy workloads can turn this into a hotspot. A head index or queue/deque structure would keep the re-entrancy fix without the per-item memmove.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@source/units/Goccia.MicrotaskQueue.pas` around lines 104 - 109, The loop
currently calls FQueue.Delete(0) which shifts the whole TList each iteration
(O(n²)); change the queue to use a head index to make pops O(1): add a field
like FHead: Integer, push items with FQueue.Add as before, read the next task
with Task := FQueue[FHead] and then increment FHead instead of calling
FQueue.Delete(0); update the loop condition to while FHead < FQueue.Count do (or
use Count = FQueue.Count - FHead), and when FHead = FQueue.Count reset
FQueue.Clear and FHead := 0 (or periodically compact by moving remaining items
to index 0 when FHead grows past a threshold). Apply these changes around the
existing CheckExecutionTimeout / CheckInstructionLimit calls so behavior is
unchanged but per-item memmoves are removed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/language/async-generators/yield-rejected-promise.js`:
- Around line 26-34: The current promise only handles the rejection path of the
first iter.next(), so if iter.next() unexpectedly fulfills the test will hang;
modify the first iter.next() call to handle both fulfillment and rejection: on
fulfillment immediately reject (or throw) the outer promise with a clear error
(e.g. "first iter.next() unexpectedly fulfilled"), and on rejection continue to
capture firstRejection and chain the subsequent iter.next() as before
(references: iter.next(), firstRejection, chainSettled).

---

Nitpick comments:
In `@source/units/Goccia.MicrotaskQueue.pas`:
- Around line 104-109: The loop currently calls FQueue.Delete(0) which shifts
the whole TList each iteration (O(n²)); change the queue to use a head index to
make pops O(1): add a field like FHead: Integer, push items with FQueue.Add as
before, read the next task with Task := FQueue[FHead] and then increment FHead
instead of calling FQueue.Delete(0); update the loop condition to while FHead <
FQueue.Count do (or use Count = FQueue.Count - FHead), and when FHead =
FQueue.Count reset FQueue.Clear and FHead := 0 (or periodically compact by
moving remaining items to index 0 when FHead grows past a threshold). Apply
these changes around the existing CheckExecutionTimeout / CheckInstructionLimit
calls so behavior is unchanged but per-item memmoves are removed.
🪄 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: 99c09c90-7f27-4d66-9f92-a8361ec63553

📥 Commits

Reviewing files that changed from the base of the PR and between 19375d5 and cabf981.

📒 Files selected for processing (4)
  • scripts/test262_syntax_filter.py
  • source/units/Goccia.MicrotaskQueue.pas
  • tests/built-ins/Promise/microtask-ordering.js
  • tests/language/async-generators/yield-rejected-promise.js

Comment thread tests/language/async-generators/yield-rejected-promise.js
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 29, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 60 improved · 🔴 38 regressed · 309 unchanged · avg +1.3%
Bytecode: 🟢 76 improved · 🔴 165 regressed · 166 unchanged · avg -1.4%

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

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 Apr 29, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 8285 8285
Tests Passed 8244 ✅ 8285 ✅
Tests Skipped 41 0
Tests Workers 4 4
Tests Test Duration 1.91s 1.90s
Tests Lex (cumulative) 218.4ms 137.0ms
Tests Parse (cumulative) 349.9ms 354.8ms
Tests Compile (cumulative) 213.6ms
Tests Execute (cumulative) 1.72s 1.57s
Tests Engine Total (cumulative) 2.29s 2.28s
Tests Lex (avg/worker) 54.6ms 34.3ms
Tests Parse (avg/worker) 87.5ms 88.7ms
Tests Compile (avg/worker) 53.4ms
Tests Execute (avg/worker) 429.6ms 392.7ms
Tests Engine Total (avg/worker) 571.7ms 569.1ms
Benchmarks Total 407 407
Benchmarks Workers 4 4
Benchmarks Duration 2.43min 2.34min

Measured on ubuntu-latest x64.

- yield-rejected-promise.js: the first iter.next() handler only covered
  the rejection path, so an engine regression that fulfilled instead
  would hang the test until the runner's timeout. Now both branches are
  registered: fulfillment fails the outer Promise with a clear error,
  rejection captures firstRejection and chains the next call as before.

- Goccia.MicrotaskQueue.pas: replace TList.Delete(0) (O(n) shift per
  pop, O(n^2) per drain) with a head index. FHead advances as tasks run
  and the underlying list is compacted (Clear + reset) once the queue
  drains. HasPending and ClearQueue follow the head; the re-entrancy
  guarantee from the previous commit is preserved because nested drains
  see only tasks past FHead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@frostney frostney merged commit f354196 into main Apr 29, 2026
12 checks passed
@frostney frostney deleted the t3code/test262-filter-update branch April 29, 2026 22:05
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.

1 participant