Skip to content

refactor(compliance): native TOML runner and generated JSON5 tests - #1047

Merged
frostney merged 6 commits into
mainfrom
codex/issue-986-native-compliance-runners
Jul 25, 2026
Merged

refactor(compliance): native TOML runner and generated JSON5 tests#1047
frostney merged 6 commits into
mainfrom
codex/issue-986-native-compliance-runners

Conversation

@frostney

@frostney frostney commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

  • Replace the TOML Python/decoder harness with a native Pascal compliance application built on shared pin verification, process isolation, failure classification, and a versioned JSON report envelope.
  • Fail closed on suite preparation and empty discovery, distinguish malformed-input rejection from infrastructure failures, and reject invalid array-extension headers without crashing the TOML parser.
  • Replace the JSON5 Python/decoder path with a committed generated JavaScript suite that runs directly through GocciaTestRunner; there is no JSON5-specific native runner or runtime wrapper.
  • Let GocciaTestRunner own JSON5 concurrency, per-file timeouts, aggregation, exit status, and JSON reporting.
  • Add dedicated suite pins, a maintainer-only JSON5 test generator, native CI execution, and weekly TOML/JSON5 pin workflows.
  • Normal compliance execution performs no clone/fetch and requires neither Python nor Node.js. JSON5 test regeneration remains a maintainer-only Node.js operation that verifies the prepared checkout revision.
  • Related design lane: Promote test262 execution into a native GocciaTest262Runner binary #768. This PR does not implement the Test262 runner.

Closes #986

Testing

  • Verified no regressions and confirmed the new feature or bugfix in end-to-end JavaScript/TypeScript tests
  • Updated documentation
  • Optional: Verified no regressions and confirmed the new feature or bugfix in native Pascal tests (not applicable: no AST, scope, evaluator, or value-type semantics changed)
  • Optional: Verified no benchmark regressions or confirmed benchmark coverage for the change (not applicable: compliance tooling only)

Additional verification:

  • ./build.pas --clean tomlcompliancerunner testrunner
  • ./build/GocciaTestRunner tests --no-progress --output=/tmp/goccia-1047-review-interpreted.json — 11,664/11,664 passed
  • ./build/GocciaTestRunner tests --mode=bytecode --no-progress --output=/tmp/goccia-1047-review-bytecode.json — 11,664/11,664 passed
  • ./build/GocciaTestRunner tests/built-ins/TOML/parse.js tests/built-ins/JSON5/upstream-parse.js tests/built-ins/JSON5/stringify.js --jobs=8 — 133/133 passed
  • ./build/GocciaTOMLComplianceRunner --suite-dir=<pinned-checkout> --jobs=8 — 712/712 passed with zero infrastructure failures
  • Missing worker input and empty discovery both return infrastructure exit code 2; empty discovery writes no green report
  • JSON5 regeneration is byte-for-byte deterministic and rejects a checkout whose revision differs from the requested pin
  • Workflow YAML, Lefthook guards, Pascal formatting, and diff whitespace checks pass

@vercel

vercel Bot commented Jul 24, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Preview Jul 24, 2026 10:45pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ada1df42-88e1-4985-967a-0b496a425146

📥 Commits

Reviewing files that changed from the base of the PR and between 4b3cd2e and 820f3c3.

📒 Files selected for processing (1)
  • tests/built-ins/TOML/parse.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/built-ins/TOML/parse.js

📝 Walkthrough

Walkthrough

The PR replaces Python-based TOML and JSON5 compliance orchestration with native TOML execution, generated JSON5 tests, pinned-suite automation, updated build and CI workflows, documentation, and stricter TOML array redefinition validation.

Changes

Native compliance execution

Layer / File(s) Summary
Shared compliance runtime and TOML runner
source/app/compliance/Goccia.Compliance.pas, source/app/compliance/GocciaTOMLComplianceRunner.dpr, tests/compliance/toml-test.pin
Adds native process execution, timeouts, bounded concurrency, pin validation, JSON reporting, worker/coordinator modes, and TOML AST comparison.
Generated JSON5 suite and pin automation
scripts/regenerate-json5-tests.js, tests/built-ins/JSON5/upstream-parse.js, tests/compliance/json5.pin, .github/workflows/json5-test-bump.yml, scripts/suite-bump-pin.ts
Generates revision-checked JavaScript parser tests and automates JSON5 pin and fixture updates.
Build and CI runner integration
build.pas, .github/workflows/ci.yml, .github/workflows/toml-test-bump.yml
Builds compliance entrypoints, stages the TOML runner, executes both compliance jobs directly, and validates report shapes.
Runner usage documentation
docs/build-system.md, docs/testing.md, docs/built-ins-data-formats.md, docs/contributing/tooling.md, docs/interpreter.md
Documents native runners, pinned suites, generated tests, build targets, and CI behavior.

TOML parser validation

Layer / File(s) Summary
Array-to-table redefinition checks
source/units/Goccia.TOML.pas, tests/built-ins/TOML/parse.js
Rejects table definitions whose existing path resolves to an array and adds SyntaxError coverage for incompatible array redefinitions.

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

Possibly related issues

  • Issue 768 — Related native conformance-runner and shared reporting direction.

Possibly related PRs

Suggested labels: spec compliance, internal

🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning Most compliance tooling is updated, but the PR lacks the requested GocciaJSON5ComplianceRunner and changes TOML semantics outside #986. Add the native JSON5 compliance runner and keep TOML semantics unchanged so the implementation matches the linked issue scope.
Out of Scope Changes check ⚠️ Warning The TOML parser change and its added parse cases modify language behavior, which the linked scope explicitly says not to do. Move the TOML semantics change and related tests to a separate PR, or remove them if they're not required for compliance tooling.
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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and matches the main compliance-tooling refactor in the diff.
Description check ✅ Passed The PR description follows the template with Summary and Testing sections and includes the required checklist items.

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

@github-actions

github-actions Bot commented Jul 24, 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.10 runs/s
babylon pass 0.04 runs/s
buble pass 0.09 runs/s
chai pass 0.09 runs/s
coffeescript pass 0.01 runs/s
espree pass 0.02 runs/s
esprima pass 0.07 runs/s
jshint pass 0.01 runs/s
lebab pass 0.08 runs/s
postcss pass 0.04 runs/s
prepack pass 0.10 runs/s
prettier pass 0.06 runs/s
source-map pass 0.03 runs/s
terser pass 284 runs/s
typescript pass 0.11 runs/s
uglify-js pass 131 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 24, 2026

Copy link
Copy Markdown
Contributor

Suite Timing

Test Runner (interpreted: 11,664 passed; bytecode: 11,664 passed)
Metric Interpreted Bytecode
Total 11664 11664
Passed 11664 ✅ 11664 ✅
Workers 4 4
Test Duration 15.74s 17.94s
Lex (cumulative) 1.57s 1.83s
Parse (cumulative) 849.0ms 964.0ms
Compile (cumulative) 1.14s
Execute (cumulative) 339.6ms 16.65s
Engine Total (cumulative) 2.76s 20.58s
Lex (avg/worker) 392.2ms 458.5ms
Parse (avg/worker) 212.2ms 241.0ms
Compile (avg/worker) 284.3ms
Execute (avg/worker) 84.9ms 4.16s
Engine Total (avg/worker) 689.3ms 5.15s

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 67.17 MiB 64.51 MiB
GC Peak Live 215.05 MiB 185.41 MiB
GC Allocated During Run 531.07 MiB 460.27 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 226 226
GC Collected Objects 4,415,057 3,868,352
Heap Start Allocated 330.0 KiB 329.9 KiB
Heap End Allocated 2.90 MiB 2.90 MiB
Heap Delta Allocated 2.58 MiB 2.58 MiB
Heap Delta Free 2.29 MiB 2.29 MiB
Benchmarks (interpreted: 439; bytecode: 439)
Metric Interpreted Bytecode
Total 439 439
Workers 4 4
Duration 3.19min 2.86min

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 144.04 MiB 87.33 MiB
GC Allocated During Run 16.16 GiB 13.35 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 6,461 6,725
GC Collected Objects 230,510,853 293,678,635
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) 4.4ms 4.5ms
Boot (min) 4.3ms 4.4ms

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 24, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

439 benchmarks · PR vs same-runner main build

Interpreted: 🟢 37 improved · 🔴 23 regressed · 379 unchanged · avg +0.6%
Bytecode: 🟢 60 improved · 🔴 54 regressed · 325 unchanged · avg +0.3%

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

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

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 24, 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.67 0.67 17.56 366.27 26.18× 546.14×
ai-astar pass 1.62 1.61 41.29 357.21 25.58× 221.28×
gaussian-blur pass 0.49 0.51 9.60 362.24 18.98× 716.03×
raytrace-public-class-fields pass 0.40 0.41 10.95 200.74 26.89× 492.76×
sync-fs pass 1.10 1.09 31.11 226.78 28.41× 207.13×
lazy-collections pass 2.15 2.14 68.62 151.66 32.02× 70.77×

Geomean reference ratio: QuickJS 26.03×; Node.js 292.40×.

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 24, 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 22.47ms 22.63ms 1.04ms 1.08ms ~ overlap (-0.73%)
CD pass 214.98ms 216.04ms 10.61ms 9.33ms ~ overlap (-0.49%)
DeltaBlue pass 4.89ms 5.00ms 300.74µs 1.80ms ~ overlap (-2.25%)
Havlak pass 83.59s 84.20s 4061.34ms 176.60ms ~ overlap (-0.73%)
Json pass 360.51ms 362.34ms 14.50ms 4.67ms ~ overlap (-0.51%)
List pass 15.36ms 15.13ms 1.03ms 0.71ms ~ overlap (+1.51%)
Mandelbrot pass 29.04µs 28.84µs 4.44µs 88.72µs ~ overlap (+0.69%)
NBody pass 377.48µs 410.75µs 27.29µs 367.62µs ~ overlap (-8.81%)
Permute pass 42.77ms 43.31ms 1.89ms 0.69ms ~ overlap (-1.26%)
Queens pass 22.49ms 22.66ms 1.27ms 1.05ms ~ overlap (-0.74%)
Richards pass 948.86ms 949.24ms 51.75ms 6.80ms ~ overlap (-0.04%)
Sieve pass 12.30ms 12.67ms 0.55ms 0.74ms 🔴 -3.04%
Storage pass 35.24ms 35.53ms 2.90ms 0.98ms ~ overlap (-0.82%)
Towers pass 62.24ms 62.63ms 3.11ms 1.11ms ~ overlap (-0.63%)

Geomean Ratios

Ratio (row / column) Goccia main Goccia PR QuickJS 2026-06-04 NodeJS v26.5.0
Goccia main 1.000 0.988 17.190 20.393
Goccia PR 1.012 1.000 17.405 20.648
QuickJS 2026-06-04 0.058 0.057 1.000 1.186
NodeJS v26.5.0 0.049 0.048 0.843 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 24, 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 changed the title feat(compliance): replace Python TOML and JSON5 runners refactor(compliance): native TOML runner and generated JSON5 tests Jul 24, 2026
@frostney
frostney marked this pull request as ready for review July 24, 2026 18:59
@cursor

cursor Bot commented Jul 24, 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 added internal Refactoring, CI, tooling, cleanup new feature New feature or request labels Jul 24, 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.

Actionable comments posted: 4

🧹 Nitpick comments (4)
.github/workflows/json5-test-bump.yml (1)

23-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Pin the Node version used to generate the committed suite.

bun is set up explicitly, but the regeneration step runs the runner's default node, so the committed upstream-parse.js depends on whatever Node ubuntu-latest ships. Since the generator's output (number formatting, JSON.stringify escaping) is committed and diffed, add a pinned actions/setup-node step for reproducibility.

♻️ Proposed addition
       - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
+
+      - uses: actions/setup-node@<pinned-sha> # v6
+        with:
+          node-version: '22'

Also applies to: 43-48

🤖 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/json5-test-bump.yml around lines 23 - 24, Add a pinned
actions/setup-node step in the workflow before the regeneration commands, and
configure it to use the Node version required for generating the committed
suite. Keep the existing oven-sh/setup-bun step unchanged and ensure all
regeneration steps use the pinned Node installation.
source/app/compliance/Goccia.Compliance.pas (1)

141-199: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: StdErrStream is unreachable dead state.

poStderrToOutPut merges stderr into Output, so StdErrStream is never written and Result.StdErrText is always empty. Either drop the stream or use poUsePipes without poStderrToOutPut and drain ProcessRunner.Stderr separately if separate capture is wanted.

🤖 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 `@source/app/compliance/Goccia.Compliance.pas` around lines 141 - 199, Update
RunComplianceProcess to remove the unreachable StdErrStream state and its
Result.StdErrText assignment, since poStderrToOutPut merges stderr into
ProcessRunner.Output; alternatively, remove that option and drain
ProcessRunner.Stderr separately if separate stderr capture is required. Keep the
chosen stream-capture behavior consistent throughout the function.
scripts/regenerate-json5-tests.js (1)

17-32: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Upstream code is loaded before the revision is verified.

require(path.join(suiteDir, "lib")) on Line 21 executes the checkout's module code before the git rev-parse check on Line 28 can reject a wrong/unexpected revision, so the pin check provides no protection against running unintended upstream code. Verify first, then load. Validating revision as 40-hex would also fail fast on a typo.

♻️ Proposed reordering
 const suiteDir = path.resolve(process.argv[2]);
 const revision = process.argv[3];
 const outputPath = path.resolve(process.argv[4]);
 const testDir = path.join(suiteDir, "test");
-const realJSON5 = require(path.join(suiteDir, "lib"));
 const checkoutRevision = execFileSync(
   "git",
   ["-C", suiteDir, "rev-parse", "HEAD"],
   { encoding: "utf8" },
 ).trim();
 
 if (checkoutRevision !== revision) {
   throw new Error(
     `Suite revision mismatch: expected ${revision}, got ${checkoutRevision}`,
   );
 }
+
+const realJSON5 = require(path.join(suiteDir, "lib"));
🤖 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/regenerate-json5-tests.js` around lines 17 - 32, Move the realJSON5
require in the regenerate flow to after the checkoutRevision comparison, so the
expected revision is validated before any suite module code executes. Also
validate that revision is a 40-character hexadecimal commit identifier before
invoking git, while preserving the existing mismatch error for valid revisions.
.github/workflows/ci.yml (1)

204-219: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: guard against an empty compliance glob.

nullglob is still active from Line 165, so if source/app/compliance/*.dpr ever matches nothing this loop silently builds zero binaries — mirroring the explicit emptiness check used for ./source/app/*.dpr would keep the failure at the build step rather than the staging step.

🤖 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 204 - 219, Add an explicit emptiness
check for the compliance source glob before the build loop, matching the
existing check for ./source/app/*.dpr. Ensure the workflow fails immediately
when no files match, rather than silently skipping all compliance builds; keep
the existing compilation loop unchanged for non-empty matches.
🤖 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 @.github/workflows/ci.yml:
- Around line 496-507: The JSON5 revision validation in the CI step does not
affect the step status because its result is ignored before GocciaTestRunner
runs. Update the workflow around the pin check and test_runner invocation so a
failed grep for the expected revision immediately fails the step, while
preserving the existing test execution for matching pins.
- Around line 412-425: Update the “Run TOML 1.1.0 compliance suite” shell block
to enable strict error handling with set -euo pipefail before suite preparation,
so failures from git init, fetch, or checkout abort immediately and the runner
is not invoked.

In `@source/app/compliance/GocciaTOMLComplianceRunner.dpr`:
- Around line 428-438: Update the exception handling in the worker’s shown
try/except block so only EGocciaTOMLParseError writes the message and exits with
status 1; change the generic Exception handler to exit with status 2 while
preserving its error reporting. This ensures ExecuteCase classifies non-parse
failures as coInfrastructure.
- Around line 482-521: The compliance runner must fail fast when DiscoverCases
returns no cases. Immediately after discovering cases and before creating or
running TComplianceCoordinator, check whether the collection is empty, report
the discovery failure, set a nonzero Result, and exit through the existing
cleanup path without producing a successful report.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 204-219: Add an explicit emptiness check for the compliance source
glob before the build loop, matching the existing check for ./source/app/*.dpr.
Ensure the workflow fails immediately when no files match, rather than silently
skipping all compliance builds; keep the existing compilation loop unchanged for
non-empty matches.

In @.github/workflows/json5-test-bump.yml:
- Around line 23-24: Add a pinned actions/setup-node step in the workflow before
the regeneration commands, and configure it to use the Node version required for
generating the committed suite. Keep the existing oven-sh/setup-bun step
unchanged and ensure all regeneration steps use the pinned Node installation.

In `@scripts/regenerate-json5-tests.js`:
- Around line 17-32: Move the realJSON5 require in the regenerate flow to after
the checkoutRevision comparison, so the expected revision is validated before
any suite module code executes. Also validate that revision is a 40-character
hexadecimal commit identifier before invoking git, while preserving the existing
mismatch error for valid revisions.

In `@source/app/compliance/Goccia.Compliance.pas`:
- Around line 141-199: Update RunComplianceProcess to remove the unreachable
StdErrStream state and its Result.StdErrText assignment, since poStderrToOutPut
merges stderr into ProcessRunner.Output; alternatively, remove that option and
drain ProcessRunner.Stderr separately if separate stderr capture is required.
Keep the chosen stream-capture behavior consistent throughout the function.
🪄 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: 55a8bf33-e107-4d44-bd58-7033ca5dad06

📥 Commits

Reviewing files that changed from the base of the PR and between 3c7f5a4 and 6690045.

📒 Files selected for processing (20)
  • .github/workflows/ci.yml
  • .github/workflows/json5-test-bump.yml
  • .github/workflows/toml-test-bump.yml
  • build.pas
  • docs/build-system.md
  • docs/built-ins-data-formats.md
  • docs/contributing/tooling.md
  • docs/interpreter.md
  • docs/testing.md
  • scripts/GocciaJSON5Check.dpr
  • scripts/GocciaTOMLCheck.dpr
  • scripts/regenerate-json5-tests.js
  • scripts/run_json5_test_suite.py
  • scripts/run_toml_test_suite.py
  • scripts/suite-bump-pin.ts
  • source/app/compliance/Goccia.Compliance.pas
  • source/app/compliance/GocciaTOMLComplianceRunner.dpr
  • tests/built-ins/JSON5/upstream-parse.js
  • tests/compliance/json5.pin
  • tests/compliance/toml-test.pin
💤 Files with no reviewable changes (4)
  • scripts/GocciaJSON5Check.dpr
  • scripts/GocciaTOMLCheck.dpr
  • scripts/run_toml_test_suite.py
  • scripts/run_json5_test_suite.py

Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml
Comment thread source/app/compliance/GocciaTOMLComplianceRunner.dpr
Comment thread source/app/compliance/GocciaTOMLComplianceRunner.dpr
frostney added 2 commits July 24, 2026 20:18
Fail CI immediately on suite preparation errors, distinguish parser
rejections from infrastructure failures, and reject array extension headers
without crashing the TOML parser.
@coderabbitai coderabbitai Bot added spec compliance Mismatch against official JavaScript/TypeScript specification and removed new feature New feature or request labels Jul 24, 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)
tests/built-ins/TOML/parse.js (1)

138-149: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover dotted-key assignment after an array.

These cases exercise regular-table and table-array parsing, but not the new EnsureDottedKeyTable branch in source/units/Goccia.TOML.pas (Lines [935-936]). Add a case such as:

Suggested test
+    expect(() =>
+      TOML.parse(`
+items = []
+items.metadata = true
+`),
+    ).toThrow(SyntaxError);
🤖 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 `@tests/built-ins/TOML/parse.js` around lines 138 - 149, Extend the TOML parser
tests around the existing array/table-array cases to cover dotted-key assignment
after an array, exercising the EnsureDottedKeyTable path in TOML.parse. Add a
focused valid or invalid fixture matching the intended behavior, while
preserving the current regular-table and table-array assertions.
🤖 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 `@tests/built-ins/TOML/parse.js`:
- Around line 138-149: Extend the TOML parser tests around the existing
array/table-array cases to cover dotted-key assignment after an array,
exercising the EnsureDottedKeyTable path in TOML.parse. Add a focused valid or
invalid fixture matching the intended behavior, while preserving the current
regular-table and table-array assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: af547358-3683-4844-ba5d-612f88abb0b5

📥 Commits

Reviewing files that changed from the base of the PR and between 6690045 and 4b3cd2e.

📒 Files selected for processing (4)
  • .github/workflows/ci.yml
  • source/app/compliance/GocciaTOMLComplianceRunner.dpr
  • source/units/Goccia.TOML.pas
  • tests/built-ins/TOML/parse.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • source/app/compliance/GocciaTOMLComplianceRunner.dpr
  • .github/workflows/ci.yml

@frostney
frostney merged commit 2885efd into main Jul 25, 2026
126 checks passed
@frostney
frostney deleted the codex/issue-986-native-compliance-runners branch July 25, 2026 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

Replace TOML and JSON5 Python compliance machinery with native runners

1 participant