Skip to content

fix(conformance): preserve ceil boundaries and pin truthful library probes#998

Merged
frostney merged 6 commits into
mainfrom
codex/fix-library-conformance-evidence
Jul 22, 2026
Merged

fix(conformance): preserve ceil boundaries and pin truthful library probes#998
frostney merged 6 commits into
mainfrom
codex/fix-library-conformance-evidence

Conversation

@frostney

@frostney frostney commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • Fix Math.ceil so non-integral Number values above the signed 32-bit boundary stay in binary64 instead of narrowing through the FreePascal integer result. The regression covers the confirmed Math.ceil(4294967295 / 2) boundary and its negative counterpart.
  • Add a bounded es-toolkit 1.49.0 validation lane pinned to release commit c8d3c367dd509f5d8f137c6b623a30926fecd1f4 and npm SHA-512 integrity. Downloads are restricted to HTTPS on registry.npmjs.org, including redirects. It reports exact named probes and does not reuse or publish unreproduced whole-suite percentages.
  • Run the validation lane and its focused checks with Bun, matching the project scripting convention. Both CI workflows restore the same tarball cache keyed from the pinned integrity value.
  • Keep semantic failures separate from bytecode divergence, disabled capabilities, host globals, and harness failures. Known bytecode TDZ outcomes are accepted only when the interpreter passes and the bytecode error matches the pinned ReferenceError pattern.
  • Preserve the sandbox-first boundary: no Buffer, Blob, or process stubs; no unsafe Function-constructor flag. Function remains disabled by default and host globals are observations rather than ECMAScript conformance failures.
  • Spec evidence: ECMA-262 ES2026 §21.3.2.10, TC39 MCP snapshot 0248456c758431e4bb8e5d26333ff1865123c9cd.

Testing

  • Verified no regressions and confirmed the bugfix in end-to-end JavaScript tests
    • ./build/GocciaTestRunner tests: 1,442 files, 11,520/11,520 tests, 25,745 assertions
    • ./build/GocciaTestRunner tests --mode=bytecode: 1,442 files, 11,520/11,520 tests, 25,745 assertions
    • Clean loader boundary probe returns 2147483648 in interpreter and bytecode modes
    • Pinned es-toolkit report: all five interpreter probes pass; one passes both modes; four exact known transitive-import bytecode divergences; zero semantic failures; zero harness failures
    • The Bun and committed Python runners produce the same normalized report contract when run against the same pinned tarball; only temporary extraction paths and process timing telemetry are excluded
    • bun run scripts/test-es-toolkit-validation.ts
    • bun run scripts/check-test-structure.ts
    • actionlint -shellcheck= .github/workflows/pr.yml .github/workflows/ci.yml
    • Documentation symbol, duplication, length, and link checks
    • ./format.pas --check
  • Updated documentation
  • Optional: native Pascal tests (not applicable; the observable built-in behavior is covered through the public JavaScript surface)
  • Optional: benchmark coverage (not applicable; this is a correctness and evidence-classification change)

frostney added 2 commits July 21, 2026 17:20
Keep Math.ceil calculations in binary64 so values above the signed
32-bit boundary are not narrowed before reaching the Number value.
Validate named public-package behaviors against the integrity-pinned
es-toolkit release and keep semantic failures, bytecode divergence,
disabled capabilities, host globals, and harness failures distinct.
@vercel

vercel Bot commented Jul 21, 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 Preview Jul 22, 2026 4:37pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 095e6f64-c4f4-4a73-a094-75ab21939858

📥 Commits

Reviewing files that changed from the base of the PR and between af510c4 and 81f51b5.

📒 Files selected for processing (1)
  • scripts/test-es-toolkit-validation.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/test-es-toolkit-validation.ts

📝 Walkthrough

Walkthrough

The PR adds a pinned es-toolkit compatibility probe lane with harnesses, integrity-checked package handling, dual-mode execution, classified JSON reports, CI integration, tests, and documentation. It also updates Math.ceil computation and adds large-boundary tests.

Changes

Pinned es-toolkit validation

Layer / File(s) Summary
Probe manifest and harness contracts
scripts/es_toolkit_harness/manifest.json, scripts/es_toolkit_harness/*.mjs
The manifest pins es-toolkit metadata, module mappings, probe definitions, environment expectations, and known bytecode divergences; harnesses emit structured probe results.
Pinned package execution and classification
scripts/run_es_toolkit_validation.ts, scripts/test-es-toolkit-validation.ts
The Bun runner validates and extracts the package, generates import maps, executes probes in interpreted and bytecode modes, classifies outcomes, builds reports, and is covered by focused tests.
Report generation and CI integration
.github/workflows/ci.yml, .github/workflows/pr.yml, docs/es-toolkit-validation.md, docs/testing.md
CI caches the pinned tarball, runs validation, uploads the JSON report, and documents execution, classifications, scope, and workflow integration.

Math.ceil behavior

Layer / File(s) Summary
Math.ceil computation and boundary tests
source/units/Goccia.Builtins.Math.pas, tests/built-ins/Math/ceil.js
MathCeil separates special-value and integral handling, computes non-integral results without runtime Ceil, and tests values around 32-bit boundaries.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CI
  participant ValidationRunner
  participant Goccia
  participant ProbeHarness
  participant ArtifactStore
  CI->>ValidationRunner: validate runner and compute integrity cache key
  CI->>ArtifactStore: restore pinned es-toolkit tarball
  ValidationRunner->>ValidationRunner: verify package and generate import map
  ValidationRunner->>Goccia: execute probes in interpreted and bytecode modes
  Goccia->>ProbeHarness: run es-toolkit harness
  ProbeHarness-->>ValidationRunner: return structured result marker
  ValidationRunner->>ValidationRunner: classify outcomes and build JSON report
  ValidationRunner-->>CI: write es-toolkit-validation.json
  CI->>ArtifactStore: upload validation report
Loading

Possibly related PRs

Suggested labels: internal, bug, spec compliance

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly captures the two main changes: preserving Math.ceil boundaries and adding pinned es-toolkit probes.
Description check ✅ Passed The description matches the template with Summary and Testing sections and includes the key implementation and validation details.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Web Tooling Benchmark

Workload Status Goccia
acorn pass 0.03 runs/s
babel pass 0.01 runs/s
babel-minify pass 0.09 runs/s
babylon pass 0.04 runs/s
buble pass 0.09 runs/s
chai pass 0.10 runs/s
coffeescript pass 0.01 runs/s
espree pass 0.03 runs/s
esprima pass 0.04 runs/s
jshint pass 0.01 runs/s
lebab pass 0.09 runs/s
postcss pass 0.02 runs/s
prepack pass 0.14 runs/s
prettier pass 0.07 runs/s
source-map pass 0.03 runs/s
terser pass 204 runs/s
typescript pass 0.11 runs/s
uglify-js pass 128 runs/s

18 pinned Web Tooling workloads; 18 workloads produced at least one Goccia sample. Raw results from 1 sample per workload; full stdout/stderr for failures and min/max/CV stay in the web-tooling-report artifact. This lane is Goccia-only by design.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Suite Timing

Test Runner (interpreted: 11,520 passed; bytecode: 11,520 passed)
Metric Interpreted Bytecode
Total 11520 11520
Passed 11520 ✅ 11520 ✅
Workers 4 4
Test Duration 15.63s 18.04s
Lex (cumulative) 1.60s 1.81s
Parse (cumulative) 853.2ms 967.9ms
Compile (cumulative) 1.16s
Execute (cumulative) 257.2ms 16.53s
Engine Total (cumulative) 2.71s 20.47s
Lex (avg/worker) 400.5ms 452.8ms
Parse (avg/worker) 213.3ms 242.0ms
Compile (avg/worker) 290.1ms
Execute (avg/worker) 64.3ms 4.13s
Engine Total (avg/worker) 678.1ms 5.12s

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 66.68 MiB 61.71 MiB
GC Peak Live 196.21 MiB 185.66 MiB
GC Allocated During Run 521.83 MiB 454.42 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 226 226
GC Collected Objects 4,375,903 3,852,519
Heap Start Allocated 326.3 KiB 326.3 KiB
Heap End Allocated 2.90 MiB 2.90 MiB
Heap Delta Allocated 2.58 MiB 2.58 MiB
Heap Delta Free 2.24 MiB 2.24 MiB
Benchmarks (interpreted: 439; bytecode: 439)
Metric Interpreted Bytecode
Total 439 439
Workers 4 4
Duration 3.08min 3.01min

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 808 B 808 B
GC Peak Live 159.33 MiB 70.02 MiB
GC Allocated During Run 18.45 GiB 9.78 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 5,829 6,137
GC Collected Objects 268,233,770 215,938,657
Heap Start Allocated 1.36 MiB 1.36 MiB
Heap End Allocated 1.37 MiB 1.37 MiB
Heap Delta Allocated 3.2 KiB 3.2 KiB
Boot
Metric Interpreted Bytecode
Boot (median) 6.3ms 6.5ms
Boot (min) 6.0ms 6.1ms

Empty-script (0;) end-to-end process wall-clock for GocciaScriptLoader, min and median over 60 runs after 10 warmups. Includes a fixed process / dynamic-loader floor that does not shrink, so it understates the engine-boot speedup; treat as practical boot time, not pure engine work.

Measured on ubuntu-latest x64.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

439 benchmarks · PR vs same-runner main build

Interpreted: 🟢 47 improved · 🔴 39 regressed · 353 unchanged · avg +0.6%
Bytecode: 🟢 62 improved · 🔴 38 regressed · 339 unchanged · avg +0.9%

Typical per-run noise (median variance): interpreted ±1.7%, bytecode ±2.0%. Deltas within noise overlap and read as unchanged.

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

Deterministic profile diff

Deterministic profile diff: no significant changes.

Measured on ubuntu-latest x64. Each PR run also builds the main base and benchmarks it back-to-back on the same runner after a warm-up discard, so the ranges compare two runs measured under the same conditions; overlapping min/max ranges are treated as unchanged noise. Percentage deltas are secondary context. See docs/adr/0076.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

JetStream 3 Performance Barometer

Workload Status Goccia main Goccia PR QuickJS Node.js vs QuickJS vs Node.js
hash-map pass 0.73 0.74 17.01 402.53 23.08× 546.15×
ai-astar pass 1.71 1.70 42.30 355.23 24.89× 209.07×
gaussian-blur pass 0.33 0.35 8.09 298.53 23.17× 854.65×
raytrace-public-class-fields pass 0.43 0.44 11.57 194.72 26.57× 447.28×
sync-fs pass 0.94 0.96 26.59 224.37 27.71× 233.84×
lazy-collections pass 2.83 2.86 91.33 201.50 31.92× 70.43×

Geomean reference ratio: QuickJS 26.06×; Node.js 299.30×.

1.00× means aligned; values above 1.00× mean Goccia was proportionally slower after normalizing JetStream’s higher-is-better score. This is a directional barometer across runtimes with different goals, not a product ranking. Raw samples and failure details remain in the jetstream-report artifact.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

AWFY Results

Target Status Goccia main Goccia PR QuickJS 2026-06-04 NodeJS v26.5.0 Δ PR vs main
Bounce pass 24.27ms 24.67ms 1.06ms 1.09ms ~ overlap (-1.65%)
CD pass 223.44ms 222.93ms 10.54ms 9.79ms ~ overlap (+0.23%)
DeltaBlue pass 5.16ms 5.17ms 305.97µs 1.85ms ~ overlap (-0.27%)
Havlak pass 87.09s 87.13s 4130.38ms 180.19ms ~ overlap (-0.04%)
Json pass 373.19ms 376.91ms 14.55ms 4.69ms 🔴 -1.00%
List pass 17.41ms 17.02ms 1.03ms 0.74ms 🟢 +2.24%
Mandelbrot pass 32.79µs 31.91µs 4.88µs 91.20µs ~ overlap (+2.69%)
NBody pass 403.71µs 416.51µs 28.12µs 392.43µs ~ overlap (-3.17%)
Permute pass 46.22ms 46.18ms 1.88ms 0.71ms ~ overlap (+0.09%)
Queens pass 24.89ms 24.78ms 1.25ms 1.07ms ~ overlap (+0.41%)
Richards pass 1026.89ms 1019.98ms 51.80ms 7.00ms ~ overlap (+0.67%)
Sieve pass 13.76ms 13.67ms 0.55ms 0.78ms ~ overlap (+0.63%)
Storage pass 37.36ms 38.64ms 2.96ms 1.00ms 🔴 -3.41%
Towers pass 66.92ms 67.12ms 3.13ms 1.14ms ~ overlap (-0.30%)

Geomean Ratios

Ratio (row / column) Goccia main Goccia PR QuickJS 2026-06-04 NodeJS v26.5.0
Goccia main 1.000 0.998 18.300 21.348
Goccia PR 1.002 1.000 18.335 21.389
QuickJS 2026-06-04 0.055 0.055 1.000 1.167
NodeJS v26.5.0 0.047 0.047 0.857 1.000

14 pinned AWFY benchmarks. Medians from 5 interleaved samples per engine; raw JSON includes min/max/CV and is attached as the awfy-report artifact. Δ compares PR Goccia median against the same-runner main Goccia median; overlapping min/max ranges are treated as unchanged noise. Rows below 0.5ms are timer-floor sensitive.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

test262 Conformance

13 timeout(s) — counted separately from ordinary conformance failures; inspect the full artifact for affected tests.

Category Run Passed Δ Pass Failed Timeouts Δ Timeout Wrap-Infra Pass-rate Δ Rate
built-ins 23,668 23,668 ±0 0 0 ±0 0 100.0% ±0pp
harness 116 116 ±0 0 0 ±0 0 100.0% ±0pp
intl402 3,349 3,340 ±0 8 1 ±0 0 99.7% ±0pp
language 23,713 23,710 -2 1 2 +2 0 100.0% ±0pp
staging 1,482 1,386 +2 86 10 -2 0 93.5% +0.1pp
total 52,328 52,220 ±0 95 13 ±0 0 99.8% ±0pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
language/expressions 100.0% ±0pp 11,101 / 11,102
intl402/Temporal 100.0% ±0pp 2,028 / 2,029
intl402/NumberFormat 99.6% ±0pp 248 / 249
Per-test deltas (+0 / -0 / timeout +2 / -2)

New timeouts (2):

  • language/identifiers/start-unicode-10.0.0-class-escaped.js
  • language/identifiers/start-unicode-10.0.0-class.js

Resolved timeouts (2):

  • staging/sm/extensions/recursion.js
  • staging/sm/TypedArray/element-setting-converts-using-ToNumber.js

Steady-state failures and timeouts are non-blocking; PASS → non-timeout failure transitions 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 July 21, 2026 16:58
@frostney

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation internal Refactoring, CI, tooling, cleanup spec compliance Mismatch against official JavaScript/TypeScript specification labels Jul 21, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
scripts/run_es_toolkit_validation.py (1)

57-67: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Path-traversal already mitigated; consider filter="data" for defense-in-depth.

Static analysis flags archive.extractall(destination) as a Zip-Slip risk, but the preceding loop already resolves every member path, checks os.path.commonpath against the destination root, and rejects anything that isn't a plain file/dir (blocking symlink-based escapes too) — so this is already safe. Passing filter="data" would make that guarantee explicit and align with Python's evolving tarfile extraction-filter defaults.

🛡️ Optional hardening
-    archive.extractall(destination)
+    archive.extractall(destination, filter="data")
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/run_es_toolkit_validation.py` around lines 57 - 67, Update the
archive extraction call in extract_verified_package to pass tarfile’s data
filter, while preserving the existing path validation and file/directory entry
checks.

Source: Linters/SAST tools

.github/workflows/ci.yml (1)

1358-1370: 🧹 Nitpick | 🔵 Trivial

Consider caching the pinned es-toolkit tarball download.

This step re-downloads and re-verifies the same pinned tarball on every CI run with no actions/cache, and since cli gates artifacts/release, a transient npm outage would block releases. This is consistent with how toml-compliance/json5-compliance already do live corpus fetches inside blocking jobs, so it's not a new pattern — but caching keyed on the pinned integrity value (shared with the identical step in .github/workflows/pr.yml) would cut redundant network round-trips and reduce that flakiness surface.

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

In @.github/workflows/ci.yml around lines 1358 - 1370, Cache the pinned
es-toolkit tarball used by Check pinned es-toolkit compatibility probes, using a
key derived from its pinned integrity value and shared with the equivalent
workflow step in pr.yml. Restore the cached tarball before running
scripts/run_es_toolkit_validation.py, while preserving validation and report
upload behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 1358-1370: Cache the pinned es-toolkit tarball used by Check
pinned es-toolkit compatibility probes, using a key derived from its pinned
integrity value and shared with the equivalent workflow step in pr.yml. Restore
the cached tarball before running scripts/run_es_toolkit_validation.py, while
preserving validation and report upload behavior.

In `@scripts/run_es_toolkit_validation.py`:
- Around line 57-67: Update the archive extraction call in
extract_verified_package to pass tarfile’s data filter, while preserving the
existing path validation and file/directory entry checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b1eb78f7-2473-4d4b-a8a5-5750971f4609

📥 Commits

Reviewing files that changed from the base of the PR and between c477011 and c3e0645.

📒 Files selected for processing (14)
  • .github/workflows/ci.yml
  • .github/workflows/pr.yml
  • docs/es-toolkit-validation.md
  • docs/testing.md
  • scripts/es_toolkit_harness/deburr-combining-marks.mjs
  • scripts/es_toolkit_harness/empty-unzip-with.mjs
  • scripts/es_toolkit_harness/environment.mjs
  • scripts/es_toolkit_harness/invariant-true.mjs
  • scripts/es_toolkit_harness/large-array-sorted-index.mjs
  • scripts/es_toolkit_harness/manifest.json
  • scripts/es_toolkit_harness/ordinal-words.mjs
  • scripts/run_es_toolkit_validation.py
  • source/units/Goccia.Builtins.Math.pas
  • tests/built-ins/Math/ceil.js

Reuse the integrity-pinned package tarball across PR and main validation
while retaining integrity checks and hardened extraction.
Repository owner deleted a comment from cursor Bot Jul 22, 2026
@frostney

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@scripts/run_es_toolkit_validation.py`:
- Around line 84-85: Validate manifest["upstream"]["tarball"] before the urlopen
call in the validation flow: require an HTTPS URL whose host is
registry.npmjs.org, and reject any redirect that changes the scheme or host
before reading the response. Keep the existing download and integrity-check
behavior for approved URLs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2dd22979-f8b1-4dc6-92cb-8db7a4ace7b6

📥 Commits

Reviewing files that changed from the base of the PR and between c3e0645 and 3711d5c.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • .github/workflows/pr.yml
  • docs/es-toolkit-validation.md
  • scripts/run_es_toolkit_validation.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/pr.yml
  • docs/es-toolkit-validation.md

Comment thread scripts/run_es_toolkit_validation.py Outdated
Validate the initial tarball URL and every redirect before opening it,
allowing only HTTPS requests to registry.npmjs.org.
@cursor

cursor Bot commented Jul 22, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai coderabbitai Bot removed the spec compliance Mismatch against official JavaScript/TypeScript specification label Jul 22, 2026
@coderabbitai coderabbitai Bot added bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification and removed documentation Improvements or additions to documentation labels Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
scripts/test-es-toolkit-validation.ts (1)

107-151: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for the remaining classification branches.

Current cases cover matching pass/fail, known divergence, and timeout, but not: (1) only one mode producing a marker (→ bytecode-divergence per run_es_toolkit_validation.ts L368-370), and (2) mismatched marker.id (→ harness-failure per L371-373). A redirect-limit-exceeded case for downloadTarball would also round out coverage.

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

In `@scripts/test-es-toolkit-validation.ts` around lines 107 - 151, Extend the
classification assertions in the test block around classifySemanticProbe to
cover a run set where only one mode has a marker and assert bytecode-divergence,
plus a run set with mismatched marker.id values and assert harness-failure. Also
add downloadTarball coverage for redirect-limit-exceeded, asserting the expected
failure behavior from that path.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@scripts/test-es-toolkit-validation.ts`:
- Around line 107-151: Extend the classification assertions in the test block
around classifySemanticProbe to cover a run set where only one mode has a marker
and assert bytecode-divergence, plus a run set with mismatched marker.id values
and assert harness-failure. Also add downloadTarball coverage for
redirect-limit-exceeded, asserting the expected failure behavior from that path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 999fcbc3-7644-455c-b479-105d0269df31

📥 Commits

Reviewing files that changed from the base of the PR and between 55b4b42 and af510c4.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml
  • .github/workflows/pr.yml
  • docs/es-toolkit-validation.md
  • scripts/run_es_toolkit_validation.ts
  • scripts/test-es-toolkit-validation.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/ci.yml
  • docs/es-toolkit-validation.md

@frostney
frostney merged commit 9d952ce into main Jul 22, 2026
49 checks passed
@frostney
frostney deleted the codex/fix-library-conformance-evidence branch July 22, 2026 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant