Skip to content

ci(workflows): scope GitHub Actions token permissions to jobs that need them#791

Merged
frostney merged 2 commits into
mainfrom
claude/xenodochial-colden-c1cc59
Jun 24, 2026
Merged

ci(workflows): scope GitHub Actions token permissions to jobs that need them#791
frostney merged 2 commits into
mainfrom
claude/xenodochial-colden-c1cc59

Conversation

@frostney

Copy link
Copy Markdown
Owner

Summary

Tightens GitHub Actions GITHUB_TOKEN permissions in ci.yml and pr.yml so write scopes live only on the jobs that publish releases, push the changelog branch, or post PR comments. Every compile / test / benchmark / compliance / artifact job now runs read-only. This applies the least-privilege pattern already used by the four *-bump.yml workflows.

Permission changes

Workflow / job Before After
ci.yml workflow default contents: write + pull-requests: write contents: read
ci.yml nightly inherited write contents: write (gh release delete/create)
ci.yml release inherited write contents: write + pull-requests: write (release upload, git push, gh pr create)
pr.yml workflow default pull-requests: write contents: read
pr.yml benchmark-comment, test262-comment inherited write contents: read + pull-requests: write
pr.yml timing-comment inherited write pull-requests: write only (no checkout)

Checkout hardeningpersist-credentials: false added to every non-pushing checkout (10 in ci.yml, 9 in pr.yml), matching the bump-workflow pattern. The release job's checkout keeps persist-credentials: true (with an inline comment) because it runs git push --force-with-lease for the changelog branch.

Key constraints / non-goals

  • The PR-comment jobs need only pull-requests: write, not issues: write (the issue's open question): GitHub's "Create an issue comment" endpoint accepts either scope, and these jobs only ever comment on PRs.
  • Job-level permissions blocks replace (not merge with) the workflow default, so each checkout-bearing comment job explicitly keeps contents: read.
  • actions/cache, same-run artifact upload/download, and the Vercel-Blob publish steps don't consume GITHUB_TOKEN write scopes (they use the runtime token / BLOB_READ_WRITE_TOKEN), so the affected jobs are safe read-only.
  • The four *-bump.yml workflows and the reusable toolchain.yml (which inherits the new read-only default) are intentionally untouched.
  • No ADR and no doc change: ADRs in this repo are engine/runtime decisions only, no doc describes the token-permission model, and the bump workflows set this precedent without one.

Closes #785

Testing

  • Verified no regressions in end-to-end JavaScript tests — clean build + full JS suite gate (Definition of Done): GocciaTestRunner tests and --mode=bytecode10,799 / 10,799 passed, 0 failed, 0 skipped in both modes. (A CI-config change cannot affect the engine; run per the project's "always run" gate.)
  • Updated documentation — N/A; no documentation describes the workflow token-permission model (confirmed during a grill-with-docs session).
  • Native Pascal tests — N/A; no AST, scope, evaluator, or value-type change.
  • Benchmarks — N/A; no engine change.

Workflow-specific verification

  • ruby -ryaml parse: both files load OK.
  • actionlint ci.yml pr.yml: finding signatures byte-identical to the HEAD baseline — zero new findings. actionlint exits 1 solely because of the pre-existing SC2012 / SC2044 / SC2086 shellcheck info/warnings in ci.yml's build run: script (~line 64), which the issue documented and this PR deliberately leaves unchanged.
  • ./format.pas --check: 366 files, all formatted correctly.
  • Independent diff review (scope-sufficiency, credential-correctness, removed-behavior): zero findings — no job is under-scoped, and the sole persist-credentials: true checkout is the only one that runs an authenticated git push.

frostney and others added 2 commits June 24, 2026 18:46
…ed them

Move write scopes off the workflow-level defaults in ci.yml and pr.yml so
only the jobs that publish releases, push the changelog branch, or post PR
comments run with write tokens; every compile, test, benchmark, compliance,
and artifact job now runs read-only.

- ci.yml default narrowed to `contents: read`; `nightly` gets `contents:
  write` (gh release delete/create) and `release` gets `contents: write` +
  `pull-requests: write` (release upload, git push, gh pr create).
- pr.yml default narrowed to `contents: read`; the three PR-comment jobs get
  `pull-requests: write` (plus `contents: read` where they check out;
  `timing-comment` has no checkout, so it gets `pull-requests: write` only).
- Add `persist-credentials: false` to every non-pushing checkout, matching
  the bump-workflow pattern; the `release` checkout keeps its credentials for
  the `git push --force-with-lease` of the changelog branch.

The PR-comment jobs need only `pull-requests: write` (not `issues: write`):
GitHub's create-issue-comment endpoint accepts either scope and these jobs
only comment on pull requests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Jun 24, 2026 5:48pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c5fb81ae-8431-4e41-9751-3c42792b6522

📥 Commits

Reviewing files that changed from the base of the PR and between 5319ade and 90d95db.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • .github/workflows/pr.yml

📝 Walkthrough

Walkthrough

Workflow-level write permissions in .github/workflows/ci.yml and .github/workflows/pr.yml are restricted to contents: read. Job-level permissions blocks granting write access are added only to nightly, release, benchmark-comment, timing-comment, and test262-comment. All other checkout steps across both files add persist-credentials: false.

Changes

GitHub Actions permissions hardening

Layer / File(s) Summary
Workflow-level permission restriction
.github/workflows/ci.yml, .github/workflows/pr.yml
Top-level permissions in both workflows are narrowed to contents: read only, removing the implicit pull-requests: write (and contents: write in ci.yml) grant that previously applied to every job.
persist-credentials: false on read-only jobs
.github/workflows/ci.yml, .github/workflows/pr.yml
All actions/checkout steps in build, test, compliance, benchmark, CLI, artifact, docs, and test262 jobs in both files are updated to set persist-credentials: false.
Job-level write permissions for publish and comment jobs
.github/workflows/ci.yml, .github/workflows/pr.yml
nightly gains contents: write with persist-credentials: false; release gains contents: write and pull-requests: write with persist-credentials: true (required for the changelog push). In pr.yml, benchmark-comment, timing-comment, and test262-comment each receive explicit pull-requests: write job-level permissions with persist-credentials: false on their checkouts.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Suggested labels

internal

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: narrowing GitHub Actions token permissions to only the jobs that need them.
Description check ✅ Passed The description matches the template with a clear summary and testing section, plus constraints, non-goals, and the linked issue.
Linked Issues check ✅ Passed The changes satisfy #785 by moving write scopes to the specific release and PR-comment jobs and keeping other jobs read-only.
Out of Scope Changes check ✅ Passed The diff stays focused on workflow permissions and checkout credential handling without unrelated code changes.
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.

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Results

430 benchmarks

Interpreted: 🟢 7 improved · 🔴 225 regressed · 198 unchanged · avg -9.1%
Bytecode: 🟢 46 improved · 🔴 27 regressed · 357 unchanged · avg +1.4%

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

Deterministic profile diff

Deterministic profile diff: no significant changes.

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

@github-actions

Copy link
Copy Markdown
Contributor

Suite Timing

Test Runner (interpreted: 10,799 passed; bytecode: 10,799 passed)
Metric Interpreted Bytecode
Total 10799 10799
Passed 10799 ✅ 10799 ✅
Workers 4 4
Test Duration 16.23s 17.53s
Lex (cumulative) 551.2ms 558.0ms
Parse (cumulative) 367.2ms 377.1ms
Compile (cumulative) 788.2ms
Execute (cumulative) 65.2ms 37.80s
Engine Total (cumulative) 983.6ms 39.52s
Lex (avg/worker) 137.8ms 139.5ms
Parse (avg/worker) 91.8ms 94.3ms
Compile (avg/worker) 197.0ms
Execute (avg/worker) 16.3ms 9.45s
Engine Total (avg/worker) 245.9ms 9.88s

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 271.52 MiB 269.28 MiB
GC Peak Live 291.87 MiB 293.90 MiB
GC Allocated During Run 433.42 MiB 425.14 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 188 188
GC Collected Objects 1,277,900 1,249,575
Heap Start Allocated 179.0 KiB 179.0 KiB
Heap End Allocated 3.65 MiB 3.65 MiB
Heap Delta Allocated 3.47 MiB 3.47 MiB
Heap Delta Free 1.65 MiB 1.65 MiB
Benchmarks (interpreted: 430; bytecode: 430)
Metric Interpreted Bytecode
Total 430 430
Workers 4 4
Duration 2.84min 2.73min

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 6.08 MiB 6.08 MiB
GC Peak Live 87.92 MiB 58.99 MiB
GC Allocated During Run 13.66 GiB 9.38 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 3,662 3,458
GC Collected Objects 212,920,506 210,213,528
Heap Start Allocated 3.35 MiB 3.35 MiB
Heap End Allocated 3.35 MiB 3.35 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions

Copy link
Copy Markdown
Contributor

test262 Conformance

🚫 Regression vs cached main baseline. 2 previously-passing test(s) now fail; pass count Δ +35. This run blocks merge — see "Newly failing" below.

Category Run Passed Δ Pass Failed Pass-rate Δ Rate
built-ins 23,643 22,516 +1 1,127 95.2% ±0pp
harness 116 116 ±0 0 100.0% ±0pp
intl402 3,341 3,332 -2 9 99.7% -0.1pp
language 23,711 23,706 +34 5 100.0% +0.1pp
staging 1,482 1,104 +2 376 74.5% +0.1pp
total 52,293 50,774 +35 1,517 97.1% +0.1pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
built-ins/TypedArray 99.9% ±0pp 1,445 / 1,446
intl402/Temporal 99.8% -0.1pp 2,024 / 2,029
built-ins/Object 99.7% ±0pp 3,401 / 3,411
Per-test deltas (+37 / -2)

Newly failing (2):

  • intl402/Temporal/ZonedDateTime/prototype/hoursInDay/dst-less-than-hour.js
  • intl402/Temporal/ZonedDateTime/prototype/hoursInDay/same-date-starts-twice.js

Newly passing (37):

  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js
  • language/expressions/call/tco-call-args.js
  • language/expressions/call/tco-member-args.js
  • language/expressions/call/tco-non-eval-function-dynamic.js
  • language/expressions/call/tco-non-eval-function.js
  • language/expressions/call/tco-non-eval-global.js
  • language/expressions/call/tco-non-eval-with.js
  • language/expressions/coalesce/tco-pos-null.js
  • language/expressions/coalesce/tco-pos-undefined.js
  • language/expressions/comma/tco-final.js
  • language/expressions/conditional/tco-cond.js
  • language/expressions/conditional/tco-pos.js
  • language/expressions/logical-and/tco-right.js
  • language/expressions/logical-or/tco-right.js
  • language/expressions/tagged-template/tco-call.js
  • language/expressions/tagged-template/tco-member.js
  • language/expressions/tco-pos.js
  • language/statements/block/tco-stmt-list.js
  • language/statements/block/tco-stmt.js
  • language/statements/do-while/tco-body.js
  • language/statements/for/tco-const-body.js
  • language/statements/for/tco-let-body.js
  • language/statements/for/tco-lhs-body.js
  • language/statements/for/tco-var-body.js
  • language/statements/if/tco-else-body.js
  • language/statements/if/tco-if-body.js
  • language/statements/labeled/tco.js
  • language/statements/return/tco.js
  • language/statements/switch/tco-case-body-dflt.js
  • language/statements/switch/tco-case-body.js
  • language/statements/switch/tco-dftl-body.js
  • language/statements/try/tco-catch-finally.js
  • language/statements/try/tco-catch.js
  • language/statements/try/tco-finally.js
  • language/statements/while/tco-body.js
  • staging/sm/TypedArray/element-setting-converts-using-ToNumber.js
  • staging/sm/TypedArray/set-same-buffer-different-source-target-types.js

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

@frostney frostney marked this pull request as ready for review June 24, 2026 18:19
@coderabbitai coderabbitai Bot added the internal Refactoring, CI, tooling, cleanup label Jun 24, 2026
@frostney frostney merged commit f8f7246 into main Jun 24, 2026
57 of 58 checks passed
@frostney frostney deleted the claude/xenodochial-colden-c1cc59 branch June 24, 2026 18:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Refactoring, CI, tooling, cleanup

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move GitHub Actions write permissions to the jobs that need them

1 participant