Skip to content

Add automated changelog generation with git-cliff#248

Merged
frostney merged 3 commits into
mainfrom
feature/changelog-automation
Apr 9, 2026
Merged

Add automated changelog generation with git-cliff#248
frostney merged 3 commits into
mainfrom
feature/changelog-automation

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 9, 2026

Summary

  • Add cliff.toml configuration for git-cliff changelog generation from git history, using verb-prefix commit parsing (no conventional commits required)
  • Add .github/release.yml to categorize GitHub auto-generated release notes by PR labels (new feature, bug, performance, spec compliance, documentation, internal)
  • Update CI release job to generate categorized release notes via orhun/git-cliff-action and auto-commit CHANGELOG.md back to main after each tagged release
  • Generate initial CHANGELOG.md covering all releases (0.1.0 through 0.6.0) plus unreleased changes
  • Label all 163 existing merged PRs with appropriate category labels
  • Document the changelog workflow in docs/build-system.md and AGENTS.md

Test plan

  • Verify git-cliff -o CHANGELOG.md produces correct output locally
  • Verify .github/release.yml categories render correctly on a future GitHub release
  • Verify the orhun/git-cliff-action step runs successfully on a tagged release
  • Verify the auto-commit step pushes CHANGELOG.md to main after release creation

🤖 Generated with Claude Code

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

coderabbitai Bot commented Apr 9, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8aa536d2-0c63-4646-9ac3-e844b2270410

📥 Commits

Reviewing files that changed from the base of the PR and between ab91897 and 9141693.

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

📝 Walkthrough

Walkthrough

Adds git-cliff-based changelog generation and GitHub release categorization: new config files, CI workflow changes to generate RELEASE_NOTES.md and full CHANGELOG.md (and open a changelog PR), plus documentation updates describing the flow.

Changes

Cohort / File(s) Summary
Changelog Configuration
cliff.toml, .github/release.yml
Add git-cliff configuration (cliff.toml) mapping commit regexes to categorized groups and templated output; add GitHub release label/category mappings and excluded labels in .github/release.yml.
CI Release Workflow
.github/workflows/ci.yml
Switch release-note generation to orhun/git-cliff-action@v4 to produce RELEASE_NOTES.md for the GitHub release, then generate CHANGELOG.md, create a changelog/<tag> branch from origin/main, conditionally commit/push CHANGELOG.md, and create a PR targeting main with an internal label. Also expanded GitHub token permissions.
Generated Changelog
CHANGELOG.md
Add a comprehensive changelog including an [Unreleased] section and historical release entries (0.1.0–0.6.0) documenting features, fixes, improvements, performance notes, and internals.
Documentation
AGENTS.md, docs/build-system.md
Document local and CI changelog generation using git-cliff and cliff.toml, CI usage of orhun/git-cliff-action, commands to regenerate CHANGELOG.md, and the PR workflow for updating the changelog.

Sequence Diagram

sequenceDiagram
    participant CI as GitHub Actions
    participant GitCliff as git-cliff-action
    participant GitHistory as Git History
    participant API as GitHub Release API
    participant Repo as Repository

    CI->>GitHistory: fetch commits/tags
    CI->>GitCliff: generate RELEASE_NOTES.md (cliff.toml)
    GitCliff->>GitHistory: parse & group commits
    GitCliff-->>CI: RELEASE_NOTES.md

    CI->>API: create GitHub release (body_path=RELEASE_NOTES.md)
    API-->>CI: release created

    CI->>GitCliff: generate full CHANGELOG.md (all history)
    GitCliff-->>CI: CHANGELOG.md

    CI->>Repo: checkout origin/main, create branch changelog/<tag>
    CI->>Repo: git add/commit CHANGELOG.md (if changed)
    CI->>Repo: push branch
    CI->>API: create PR (base: main, head: changelog/<tag>)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main change: adding automated changelog generation using git-cliff, which is reflected across all modified files (cliff.toml, .github/release.yml, CI workflow updates, and documentation).
Description check ✅ Passed The PR description includes a comprehensive summary of all changes and a test plan with checkboxes, though it deviates from the repository's template by omitting the standard structured sections (Summary with constraints/non-goals and Testing checkboxes in the required format).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

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.

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

1004-1014: Consider adding branch protection awareness for the changelog commit.

The auto-commit to main will fail silently if branch protection rules require PR reviews or status checks. This is likely intentional (the check for changes handles the no-op case), but worth noting.

If branch protection is enabled on main, you may need to:

  • Use a GitHub App token with bypass permissions, or
  • Configure the protection rules to allow the github-actions[bot] to push directly
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 1004 - 1014, The "Commit changelog to
main" workflow step can fail under branch protection; update the job to handle
protected branches by either (A) using a token with push bypass (replace
GITHUB_TOKEN with a GitHub App or PAT that has permission to bypass branch
protections) or (B) change the behavior to create a changelog pull request
instead of pushing directly (detect push failure and open a PR using the repo
mutation via GH API). Ensure you reference the step name "Commit changelog to
main" and the commit/push commands in that step when implementing the token
change or PR fallback so the workflow no longer silently fails on protected
main.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 1004-1014: The "Commit changelog to main" workflow step can fail
under branch protection; update the job to handle protected branches by either
(A) using a token with push bypass (replace GITHUB_TOKEN with a GitHub App or
PAT that has permission to bypass branch protections) or (B) change the behavior
to create a changelog pull request instead of pushing directly (detect push
failure and open a PR using the repo mutation via GH API). Ensure you reference
the step name "Commit changelog to main" and the commit/push commands in that
step when implementing the token change or PR fallback so the workflow no longer
silently fails on protected main.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cfef674f-38e5-4254-b6c9-7642867f6404

📥 Commits

Reviewing files that changed from the base of the PR and between a2e0d0e and f930566.

📒 Files selected for processing (6)
  • .github/release.yml
  • .github/workflows/ci.yml
  • AGENTS.md
  • CHANGELOG.md
  • cliff.toml
  • docs/build-system.md

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 4090 4090
Tests Passed 4049 ✅ 4090 ✅
Tests Skipped 41 0
Tests Test Duration 290.0ms 281.6ms
Tests Lex 79.1ms 54.9ms
Tests Parse 99.3ms 102.6ms
Tests Compile 64.0ms
Tests Execute 304.6ms 313.1ms
Tests Engine Total 483.0ms 534.7ms
Benchmarks Total 274 274
Benchmarks Duration 7.61min 6.80min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 9, 2026

Benchmark Results

274 benchmarks

Interpreted: 🟢 139 improved · 🔴 25 regressed · 110 unchanged · avg +1.3%
Bytecode: 🟢 8 improved · 🔴 236 regressed · 30 unchanged · avg -6.4%

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

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.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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: 2

🤖 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/ci.yml:
- Around line 1004-1026: The workflow step "Open changelog PR" fails because the
workflow permissions lack pull-requests: write (gh pr create needs it) and the
step isn't idempotent; update the workflow top-level permissions to include
pull-requests: write in addition to contents: write, make branch creation
resilient by checking for or force-creating the branch instead of using a
brittle git checkout -b (replace with an idempotent flow around git
rev-parse/checkout or git checkout -B targeting BRANCH), and before calling gh
pr create, check for an existing PR for branch "$BRANCH" (e.g., use gh pr view
or list to detect an existing PR) and skip creation if one exists to avoid
403/failure from duplicate PRs.

In `@docs/build-system.md`:
- Around line 304-343: The verb-prefix table in the docs/build-system.md is
incomplete compared to the actual patterns in cliff.toml; either expand the
table rows for the categories (Added, Fixed, Improved, Performance, Internal) to
include the extra prefixes mentioned in the review (e.g., "Ignore leading
shebang", "Normalize", "Preserve", "Merge GocciaScript metadata",
"Pre-materialize", "Mark .* inline", "Fold Souffle", etc.) or add a single
clarifying sentence under the table stating it shows common examples and point
readers to cliff.toml for the authoritative, complete list; update the table or
note and ensure the doc references cliff.toml as the source of truth.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b2e214e-8fdc-4ce8-83a8-0736631fa96a

📥 Commits

Reviewing files that changed from the base of the PR and between f930566 and ab91897.

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

Comment thread .github/workflows/ci.yml
Comment thread docs/build-system.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@frostney frostney merged commit 8db0dd6 into main Apr 9, 2026
9 checks passed
@frostney frostney deleted the feature/changelog-automation branch April 9, 2026 14:42
frostney added a commit that referenced this pull request Apr 9, 2026
Resolve conflict in AGENTS.md Build System section: keep trimmed
format from docs-cleanup, incorporate new changelog line from main
(git-cliff, #248). Error.cause (#249) already documented.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant