Skip to content

perf(json): recover UTF-16 parser hot paths#1000

Merged
frostney merged 2 commits into
mainfrom
codex/perf-json-parse-fast-path
Jul 22, 2026
Merged

perf(json): recover UTF-16 parser hot paths#1000
frostney merged 2 commits into
mainfrom
codex/perf-json-parse-fast-path

Conversation

@frostney

@frostney frostney commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • Scan ordinary unescaped JSON strings directly and copy the source slice once instead of growing a UnicodeString one character at a time.
  • Keep escape and validation semantics on the existing parser path, using TStringBuffer for escaped strings.
  • Replace number-parser WideChar set-membership checks with equivalent direct ASCII comparisons; FPC 3.2.2 otherwise lowers these checks through fpc_uchar_to_char and iconv on x86-64.
  • Add focused native coverage for unescaped UTF-16 text and the control-character fallback boundary.
  • Keep exact decimal conversion, structural UTF-16 overhead, and local-register/T4 work out of this PR because profiling identifies them as separate mechanisms.
  • Related to Close the measured throughput gap on AWFY and web-tooling hotspots #862.

Testing

  • Verified no regressions in end-to-end JavaScript tests: ./build.pas --clean testrunner, ./build/GocciaTestRunner tests, and ./build/GocciaTestRunner tests --mode=bytecode (1,442 files, 11,519 tests, 25,742 assertions in each mode).
  • Documentation not required: this changes internal parser mechanics without changing the public API or behavior.
  • Verified the native JSONParser.Test suite on macOS arm64 and Ubuntu x86-64 (54/54 passing on both).
  • Verified formatting with ./format.pas --check (429 files).
  • Confirmed the performance recovery on Ubuntu 25.10 x86-64 with FPC 3.2.2 production bytecode binaries, QuickJS 2026-06-04, 15 interleaved samples per engine, matching checksums, and ADR 0087 IQR statistics.

Measurements

Current c477011e versus the string fast path, IQR-filtered medians:

Target Main Patched Delta Main CV Patched CV
JSON parse only 120.614 ms 91.533 ms -24.11% 10.05% 4.14%
Reconstructed JSON roundtrip 96.069 ms 80.355 ms -16.36% 10.05% 3.92%
Escaped-string parse control 33.141 ms 30.017 ms -9.43% 3.00% 4.37%
JSON stringify control 48.893 ms 49.965 ms +2.19% 13.19% 3.94%

The string fix reduces parse-only retired instructions from 1,065,647,274 to 770,802,416 (-27.67%), branches from 145,668,284 to 107,413,247 (-26.26%), and branch mispredicts from 3,285,568 to 2,995,097 (-8.84%).

Same-commit string-patch versus direct-ASCII comparisons, IQR-filtered medians:

Target String patch Combined Delta Baseline CV Combined CV
Integer-only JSON parse 144.921 ms 99.925 ms -31.05% 0.57% 0.67%
Decimal-only JSON parse 444.808 ms 410.697 ms -7.67% 1.08% 1.30%
JSON parse only 82.775 ms 78.898 ms -4.68% 0.92% 0.89%
Reconstructed JSON roundtrip 72.707 ms 71.208 ms -2.06% 0.59% 0.78%
Structure-only control 162.627 ms 163.723 ms +0.67% 1.84% 0.76%

Callgrind confirms the second mechanism: the integer-only probe falls from 398,062,860 to 271,508,200 retired instructions (-31.79%). Direct comparison with the pre-regression parent leaves integer parsing +9.34%, while exact decimal conversion remains +349.14% and structure-only parsing +40.64%; those residual gaps are not bundled into this PR.

Fresh CI same-runner main versus PR measurements confirm transfer to the repository benchmark suite:

benchmarks/json.js Interpreted Bytecode
Parse simple object +30.4% +30.3%
Parse nested object +33.5% +36.7%
Parse array of objects +28.2% +24.8%
Parse large flat object +29.4% +30.5%
Parse then stringify +14.5% +24.0%
Stringify then parse +21.3% +23.3%

The pinned AWFY Json row moves only +0.73%, confirming it is not a substitute for the missing audit kernel. All 49 PR checks pass, including test262 (52,219/52,328 pass, 99.8%, no new non-timeout failures).

@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Preview Jul 21, 2026 8:43pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e7792365-d2e2-4cde-b262-0ea00d85031b

📥 Commits

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

📒 Files selected for processing (2)
  • source/shared/JSONParser.Test.pas
  • source/shared/JSONParser.pas

📝 Walkthrough

Walkthrough

The JSON parser now uses buffered string construction, explicit character comparisons for number parsing, and additional strict-mode tests for unescaped Unicode and control characters.

Changes

JSON parser updates

Layer / File(s) Summary
Parser character checks
source/shared/JSONParser.pas
Decimal, sign, leading-digit, and exponent checks now use explicit character comparisons, with StringBuffer added as a parser dependency.
Buffered string parsing and strict-mode coverage
source/shared/JSONParser.pas, source/shared/JSONParser.Test.pas
ParseString builds decoded output with TStringBuffer, while tests cover unescaped Unicode text and rejected unescaped control characters.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: performance

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and reflects the parser performance focus, though it omits the specific string and number parsing changes.
Description check ✅ Passed The description matches the template with Summary and Testing sections, required implementation notes, issue link, and detailed verification.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Web Tooling Benchmark

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

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

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Benchmark Results

439 benchmarks · PR vs same-runner main build

Interpreted: 🟢 40 improved · 🔴 40 regressed · 359 unchanged · avg +0.8%
Bytecode: 🟢 41 improved · 🔴 57 regressed · 341 unchanged · avg -0.1%

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

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

Deterministic profile diff

Deterministic profile diff: no significant changes.

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

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Suite Timing

Test Runner (interpreted: 11,519 passed; bytecode: 11,519 passed)
Metric Interpreted Bytecode
Total 11519 11519
Passed 11519 ✅ 11519 ✅
Workers 4 4
Test Duration 18.34s 16.45s
Lex (cumulative) 1.84s 1.59s
Parse (cumulative) 993.8ms 864.1ms
Compile (cumulative) 998.2ms
Execute (cumulative) 296.4ms 17.90s
Engine Total (cumulative) 3.13s 21.35s
Lex (avg/worker) 459.4ms 396.3ms
Parse (avg/worker) 248.4ms 216.0ms
Compile (avg/worker) 249.5ms
Execute (avg/worker) 74.1ms 4.47s
Engine Total (avg/worker) 781.9ms 5.34s

Memory

GC rows aggregate the main thread plus all worker thread-local GCs. Test runner worker shutdown frees thread-local heaps in bulk; that shutdown reclamation is not counted as GC collections or collected objects.

Metric Interpreted Bytecode
GC Live 65.95 MiB 62.79 MiB
GC Peak Live 209.24 MiB 178.61 MiB
GC Allocated During Run 521.81 MiB 454.40 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 226 226
GC Collected Objects 4,382,139 3,841,241
Heap Start Allocated 326.3 KiB 326.3 KiB
Heap End Allocated 2.90 MiB 2.90 MiB
Heap Delta Allocated 2.58 MiB 2.58 MiB
Heap Delta Free 2.24 MiB 2.24 MiB
Benchmarks (interpreted: 439; bytecode: 439)
Metric Interpreted Bytecode
Total 439 439
Workers 4 4
Duration 3.12min 2.95min

Memory

GC rows aggregate the main thread plus all worker thread-local GCs. Benchmark runner performs explicit between-file collections, so collection and collected-object counts can be much higher than the test runner.

Metric Interpreted Bytecode
GC Live 808 B 808 B
GC Peak Live 147.04 MiB 66.75 MiB
GC Allocated During Run 15.68 GiB 9.39 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 5,281 5,780
GC Collected Objects 230,663,630 205,218,112
Heap Start Allocated 1.36 MiB 1.36 MiB
Heap End Allocated 1.37 MiB 1.37 MiB
Heap Delta Allocated 3.2 KiB 3.2 KiB
Boot
Metric Interpreted Bytecode
Boot (median) 5.3ms 5.3ms
Boot (min) 5.2ms 5.3ms

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

Measured on ubuntu-latest x64.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

JetStream 3 Performance Barometer

Workload Status Goccia main Goccia PR QuickJS Node.js vs QuickJS vs Node.js
hash-map pass 0.52 0.53 13.53 348.24 25.77× 663.13×
ai-astar pass 1.53 1.56 39.82 334.64 25.59× 215.09×
gaussian-blur pass 0.35 0.35 7.99 303.87 23.10× 878.27×
raytrace-public-class-fields pass 0.40 0.40 11.06 186.95 27.79× 469.86×
sync-fs pass 1.28 1.28 33.93 287.17 26.52× 224.51×
lazy-collections pass 2.00 2.00 68.43 147.24 34.25× 73.69×

Geomean reference ratio: QuickJS 26.97×; Node.js 314.83×.

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

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

AWFY Results

Target Status Goccia main Goccia PR QuickJS 2026-06-04 NodeJS v26.5.0 Δ PR vs main
Bounce pass 24.47ms 24.39ms 1.06ms 1.07ms ~ overlap (+0.32%)
CD pass 223.21ms 221.67ms 10.58ms 9.60ms ~ overlap (+0.69%)
DeltaBlue pass 5.14ms 5.16ms 309.79µs 1.82ms ~ overlap (-0.49%)
Havlak pass 87.27s 86.60s 4009.32ms 186.07ms 🟢 +0.77%
Json pass 377.83ms 375.06ms 14.48ms 4.85ms 🟢 +0.73%
List pass 17.39ms 17.41ms 1.05ms 0.74ms ~ overlap (-0.09%)
Mandelbrot pass 31.29µs 30.91µs 4.87µs 88.74µs ~ overlap (+1.22%)
NBody pass 397.45µs 391.61µs 28.10µs 395.81µs ~ overlap (+1.47%)
Permute pass 46.62ms 46.41ms 1.89ms 0.71ms ~ overlap (+0.45%)
Queens pass 24.91ms 24.41ms 1.26ms 1.03ms 🟢 +2.00%
Richards pass 1029.40ms 1015.26ms 52.46ms 6.72ms 🟢 +1.37%
Sieve pass 14.08ms 13.51ms 0.56ms 0.54ms 🟢 +4.07%
Storage pass 37.56ms 37.57ms 2.93ms 1.02ms ~ overlap (-0.03%)
Towers pass 67.38ms 67.19ms 3.14ms 1.12ms ~ overlap (+0.28%)

Geomean Ratios

Ratio (row / column) Goccia main Goccia PR QuickJS 2026-06-04 NodeJS v26.5.0
Goccia main 1.000 1.009 18.250 22.060
Goccia PR 0.991 1.000 18.083 21.857
QuickJS 2026-06-04 0.055 0.055 1.000 1.209
NodeJS v26.5.0 0.045 0.046 0.827 1.000

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

@github-actions

Copy link
Copy Markdown
Contributor

test262 Conformance

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

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

Areas closest to 100%

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

New timeouts (2):

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

Resolved timeouts (1):

  • staging/sm/extensions/recursion.js

Steady-state failures and timeouts are non-blocking; PASS → non-timeout failure transitions fail the conformance gate. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached main baseline.

@frostney frostney changed the title perf(json): fast-path unescaped string parsing perf(json): recover UTF-16 parser hot paths Jul 21, 2026
@frostney
frostney marked this pull request as ready for review July 22, 2026 16:12
@cursor

cursor Bot commented Jul 22, 2026

Copy link
Copy Markdown

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

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

@frostney

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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

@frostney

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

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

@coderabbitai coderabbitai Bot added the performance Performance improvement label Jul 22, 2026
@frostney
frostney merged commit 6681354 into main Jul 22, 2026
49 checks passed
@frostney
frostney deleted the codex/perf-json-parse-fast-path branch July 22, 2026 19:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

performance Performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant