Skip to content

Update unsupported CPU target case in CI workflow#217

Merged
frostney merged 1 commit into
mainfrom
fix/cross-package-bootstrap
Apr 9, 2026
Merged

Update unsupported CPU target case in CI workflow#217
frostney merged 1 commit into
mainfrom
fix/cross-package-bootstrap

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 8, 2026

Summary

  • Replace the manually maintained package allowlist in toolchain.yml (rtl-objpas, rtl-generics, fcl-process + source copies of fcl-base and regexpr) with FPC's make packages, which builds all standard packages for each cross target
  • Simplify ci.yml to use a single -Fu"${UNITS_DIR}/*" wildcard instead of 6 separate -Fu paths per compilation command
  • Bump cache version to v31 to trigger a fresh toolchain build

Motivation

Fixes #170 — the curated package approach meant every new standard FPC dependency (like Base64 from fcl-base) risked a CI failure requiring per-package CI edits. The new approach installs compiled units into the standard units/$TARGET/* tree so any shipped FPC/FCL package is automatically available.

What changed

File Change
toolchain.yml build_target() reduced from ~80 lines of manual per-unit compilation to make packages + install loop (~15 lines). Removed source copies of fcl-base/regexpr.
ci.yml 6 package path variables → 1 UNITS_DIR. Per-package -Fu chains → single -Fu"${UNITS_DIR}/*" wildcard.
docs/build-system.md Updated cross-compilation documentation to reflect the new approach.

Test plan

  • Verify the toolchain cache rebuilds successfully with make packages for all 5 cross targets
  • Verify all 6 platform builds succeed in CI with the wildcard -Fu path
  • Verify JavaScript tests, Pascal unit tests, TOML/JSON5 compliance, benchmarks, and examples all pass

🤖 Generated with Claude Code

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

The GitHub Actions workflow adds error handling to the CPU dispatch logic by introducing a default case that rejects unsupported CPU targets with a logged error message and exit code 1, preventing silent failures for unrecognized architectures.

Changes

Cohort / File(s) Summary
Error Handling for CPU Dispatch
.github/workflows/toolchain.yml
Added a default (*) case branch in build_target's CPU dispatch statement that logs an error and exits with code 1 when an unsupported CPU target is provided.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description describes a comprehensive refactoring (make packages, UNITS_DIR consolidation, docs updates), but only the CPU error handler was actually implemented; the main refactoring was reverted due to FPC assembler bugs. Update the description to clarify that the full refactoring was reverted and only the unsupported-CPU guard remains; document why the revert occurred.
Linked Issues check ⚠️ Warning Issue #170 requires replacing curated package approach with make packages, but the PR only adds an error handler and reverted the main implementation due to FPC 3.2.2 assembler incompatibility. Either complete the refactoring or update issue #170 to reflect that the approach is deferred pending FPC trunk adoption; clarify the blocker and timeline.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The unsupported CPU target error handler in toolchain.yml is a reasonable defensive improvement and aligns with the general CI robustness goals, even though it's narrower than the originally planned changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title accurately describes the main change: adding a default case handler for unsupported CPU targets in the CI workflow's build_target function.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

@frostney frostney force-pushed the fix/cross-package-bootstrap branch from 24401db to a7070b0 Compare April 8, 2026 12:06
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/toolchain.yml:
- Around line 288-299: After copying package unit dirs, add a hard validation
that at least one package was installed for the current ${target} and fail the
job if not; use the same units_base/target variables used in the loop
(pkg_units_dir, units_base, target) to compute the installed count (e.g. count
directories under "${units_base}"/*/) and if the count is zero (or below your
required representative non-RTL threshold) print a clear error and exit 1 so the
workflow stops before saving the cache.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: e8fe5de8-633a-4c19-b7f9-fece74f88f82

📥 Commits

Reviewing files that changed from the base of the PR and between 11fe493 and a7070b0.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • .github/workflows/toolchain.yml
  • docs/build-system.md

Comment thread .github/workflows/toolchain.yml Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 4037 4037
Tests Passed 3996 ✅ 4037 ✅
Tests Skipped 41 0
Tests Test Duration 282.2ms 285.8ms
Tests Lex 77.0ms 53.6ms
Tests Parse 96.6ms 102.0ms
Tests Compile 64.7ms
Tests Execute 298.7ms 316.6ms
Tests Engine Total 472.3ms 536.9ms
Benchmarks Total 274 274
Benchmarks Duration 7.63min 6.26min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 8, 2026

Benchmark Results

274 benchmarks

Interpreted: 🟢 177 improved · 🔴 32 regressed · 65 unchanged · avg +4.3%
Bytecode: 🟢 20 improved · 🔴 206 regressed · 48 unchanged · avg -3.7%

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

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/toolchain.yml:
- Around line 262-267: The case statement selecting the compiler wrapper (case
"$cpu" in ... ) currently handles only x86_64, i386, and aarch64 and lacks a
default branch; add an explicit unsupported-CPU guard by adding a default case
(*) that logs/echoes a clear error (including the offending $cpu value) and
exits non‑zero so builds fail fast when CPU is not one of the three supported
values—update the block that sets local wrapper and the case "$cpu" in construct
to include this hard-fail branch.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: c2fe4039-efcb-4ae9-990e-ac21be9ef19b

📥 Commits

Reviewing files that changed from the base of the PR and between a7070b0 and b6ddad3.

📒 Files selected for processing (1)
  • .github/workflows/toolchain.yml

Comment thread .github/workflows/toolchain.yml Outdated
coderabbitai[bot]
coderabbitai Bot previously requested changes Apr 8, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/toolchain.yml:
- Around line 139-161: The Darwin as-fix shim created under PREFIX (the script
at $PREFIX/lib/as-fix/as) isn't added to PATH for downstream Darwin compilation
steps that invoke CROSS_FPC, so FPC can call /usr/bin/as directly and hit the
Xcode 16.4 CFI-label error; fix by ensuring the shim is always visible to
downstream jobs: either prepend $PREFIX/lib/as-fix to PATH in the CI steps that
run CROSS_FPC for Darwin targets (ci.yml steps that call $CROSS_FPC), or install
the shim into the toolchain wrapper (e.g., integrate invocation into the
generated fpc wrapper at $PREFIX/bin/fpc) so every invocation of CROSS_FPC uses
the shim.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: c75cff85-df4f-4681-b55f-263362f35c08

📥 Commits

Reviewing files that changed from the base of the PR and between 4279379 and f191017.

📒 Files selected for processing (1)
  • .github/workflows/toolchain.yml

Comment thread .github/workflows/toolchain.yml Outdated
Add a default case to the CPU selection that fails fast with a clear
error instead of silently falling through with unset variables.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@frostney frostney force-pushed the fix/cross-package-bootstrap branch from bde5f60 to bb30aa4 Compare April 9, 2026 08:31
@frostney
Copy link
Copy Markdown
Owner Author

frostney commented Apr 9, 2026

Summary

Reverted to the existing curated approach with one small improvement: an unsupported-CPU guard in the build_target case statement (from CodeRabbit review).

What was attempted

The goal was to replace the curated per-package build with make packages (FPC's fpmake system) to build all packages automatically. This hit a fundamental blocker:

FPC 3.2.2 + Xcode 16.4 assembler incompatibility: FPC generates .globl labels inside .cfi_startproc/.cfi_endproc pairs. Clang's assembler rejects these ("non-private labels cannot appear between .cfi_startproc / .cfi_endproc pairs"). This is a known FPC 3.2.2 bug fixed in FPC trunk.

Multiple workarounds were attempted and all failed:

  • Intercepting as (PATH, -FD, compiler directory) — FPC hardcodes the SDK assembler path on macOS, ignoring PATH and -FD
  • Post-hoc .s file fixing — fpmake cleans its output between runs, destroying the fixes
  • -s flag (skip assembly) — leaks into fpmake bootstrap, preventing the fpmake binary from being linked
  • Label renaming (_$L$) — too broad (breaks .globl); too narrow (misses affected labels)
  • CFI stripping — works for assembly but fpmake regenerates files on re-run

Why revert is the right call

The curated approach on main already covers all packages GocciaScript uses:

  • Compiled: rtl, rtl-objpas, rtl-generics, fcl-process
  • Source-copied: fcl-base, regexpr

There are no missing packages today. The make packages approach can be revisited when FPC trunk (which fixes the assembler bug) is adopted — tracked in a separate issue.

What this PR now contains

Just the unsupported-CPU guard from CodeRabbit's review — a *) exit 1 default case in the build_target wrapper selection.

@frostney frostney changed the title Replace curated cross-package CI bootstrap with make packages Update unsupported CPU target case in CI workflow Apr 9, 2026
@frostney frostney dismissed coderabbitai[bot]’s stale review April 9, 2026 08:44

Outdated and the scope has shifted

@frostney frostney merged commit 1ddf91a into main Apr 9, 2026
9 checks passed
@frostney frostney deleted the fix/cross-package-bootstrap branch April 9, 2026 08:45
@frostney frostney added the internal Refactoring, CI, tooling, cleanup label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Refactoring, CI, tooling, cleanup

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replace curated cross-package CI bootstrap with proper FPC package installation

1 participant