Skip to content

Cache compiled RegExp programs#677

Merged
frostney merged 1 commit into
mainfrom
t3code/issue-596-fix
May 20, 2026
Merged

Cache compiled RegExp programs#677
frostney merged 1 commit into
mainfrom
t3code/issue-596-fix

Conversation

@frostney
Copy link
Copy Markdown
Owner

Summary

  • Split compiled RegExp program record types into Goccia.RegExp.&Program so the engine, compiler, and VM can share them without the old validation dependency.
  • Compile a RegExp pattern once during object construction and store the compiled TRegExpProgram on the RegExp object for native execution paths.
  • Route native exec, test, match, matchAll, search, replace, and split matching through the cached program instead of recompiling per match.
  • Closes Cache compiled RegExp program to eliminate per-match recompilation #596.

Testing

  • Verified no regressions and confirmed the new feature or bugfix in end-to-end JavaScript/TypeScript tests
  • Updated documentation (not applicable; internal performance change)
  • Optional: Verified no regressions and confirmed the new feature or bugfix in native Pascal tests (if AST, scope, evaluator, or value types changed)
  • Optional: Verified no benchmark regressions or confirmed benchmark coverage for the change

Compile RegExp patterns once during object construction and store the compiled program on the object for native execution paths.

Closes #596
@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored May 20, 2026 1:18pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

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

Run ID: 5671f987-8ac5-4f33-84c5-bd2a1400b062

📥 Commits

Reviewing files that changed from the base of the PR and between a1a0ad5 and 72deabe.

📒 Files selected for processing (6)
  • source/units/Goccia.RegExp.Compiler.pas
  • source/units/Goccia.RegExp.Engine.pas
  • source/units/Goccia.RegExp.Program.pas
  • source/units/Goccia.RegExp.Runtime.pas
  • source/units/Goccia.RegExp.VM.pas
  • source/units/Goccia.Values.ObjectValue.pas

📝 Walkthrough

Walkthrough

This PR implements caching of compiled RegExp programs to eliminate recompilation overhead. A new Goccia.RegExp.Program unit centralizes compiled-program data structures. The Engine gains compilation and execution APIs for precompiled programs. RegExp objects now store and reuse compiled programs via a new RegExpData property on TGocciaObjectValue. Runtime and Compiler are refactored to integrate the caching layer throughout the pattern-matching flow.

Changes

RegExp Program Caching and Reuse

Layer / File(s) Summary
Compiled program data model
source/units/Goccia.RegExp.Program.pas
New unit defines record types for compiled regex bytecode, character classes, capture metadata, and named groups, providing the central contract for cached program representation.
Engine compilation and execution APIs
source/units/Goccia.RegExp.Engine.pas
CompileRegExpProgram compiles and returns a cached program; ExecuteCompiledRegExp executes precompiled programs with result/group population; ExecuteRegExp refactored as wrapper; named-group types moved to Program unit.
RegExp object program storage
source/units/Goccia.Values.ObjectValue.pas
TGocciaObjectValue gains FRegExpData field and published RegExpData property with managed setter and destructor cleanup for storing compiled program data.
Runtime program caching and dispatch
source/units/Goccia.RegExp.Runtime.pas
CreateRegExpObject compiles programs at construction; new TGocciaRegExpProgramData wrapper encapsulates compiled state; MatchRegExpObject dispatches to ExecuteCompiledRegExp when cached program exists, avoiding recompilation.
Compiler refactoring
source/units/Goccia.RegExp.Compiler.pas
Public regex types and ValidateRegExpPatternNew procedure moved/removed; interface dependency shifts to Program unit; internal Engine dependency retained in implementation.
VM dependency
source/units/Goccia.RegExp.VM.pas
Interface uses list updated to include Goccia.RegExp.Program for program data structure access.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • frostney/GocciaScript#585: Refactors the newly introduced regex compiler/VM architecture by moving compiled-regex types into Goccia.RegExp.&Program and changes Engine/Runtime to compile then execute precompiled programs, which directly builds on the same custom regex compiler and VM work.
  • frostney/GocciaScript#207: Updates the RegExp engine/runtime to support named capture groups with the same d/v flag handling, with the main PR additionally refactoring named-group metadata into the new compiled TRegExpProgram/ExecuteCompiledRegExp pipeline.
  • frostney/GocciaScript#621: Moves core character-class/range and TRegExpProgram types out of Compiler into Program, while the retrieved PR extends Compiler to compile v (UnicodeSets) character-class syntax using those same range/class representations—tightly code-connected.

Suggested labels

new feature, performance, internal

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Cache compiled RegExp programs' accurately and concisely describes the main change: caching compiled RegExp programs to avoid redundant compilation.
Description check ✅ Passed The description covers the key implementation details, includes the linked issue reference (Closes #596), and provides testing status with checkboxes.
Linked Issues check ✅ Passed All code changes directly address issue #596 requirements: splitting program types into shared unit, compiling once at RegExp construction, storing the compiled program, and routing native operations through the cached program.
Out of Scope Changes check ✅ Passed All changes are focused on implementing the caching mechanism for compiled RegExp programs; no unrelated modifications to other components or features were detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

@github-actions
Copy link
Copy Markdown
Contributor

Suite Timing

Test Runner (interpreted: 9,736 passed; bytecode: 9,736 passed)
Metric Interpreted Bytecode
Total 9736 9736
Passed 9736 ✅ 9736 ✅
Workers 4 4
Test Duration 2.91s 3.21s
Lex (cumulative) 414.8ms 319.9ms
Parse (cumulative) 282.6ms 279.0ms
Compile (cumulative) 657.6ms
Execute (cumulative) 2.78s 3.22s
Engine Total (cumulative) 3.48s 4.48s
Lex (avg/worker) 103.7ms 80.0ms
Parse (avg/worker) 70.6ms 69.8ms
Compile (avg/worker) 164.4ms
Execute (avg/worker) 696.1ms 805.1ms
Engine Total (avg/worker) 870.5ms 1.12s

Memory

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

Metric Interpreted Bytecode
GC Live 278.77 MiB 273.09 MiB
GC Peak Live 278.78 MiB 273.10 MiB
GC Allocated During Run 283.22 MiB 277.54 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 1 1
GC Collected Objects 88 88
Heap Start Allocated 157.8 KiB 157.8 KiB
Heap End Allocated 1.53 MiB 1.53 MiB
Heap Delta Allocated 1.37 MiB 1.37 MiB
Heap Delta Free 1.16 MiB 1.16 MiB
Benchmarks (interpreted: 407; bytecode: 407)
Metric Interpreted Bytecode
Total 407 407
Workers 4 4
Duration 2.44min 2.38min

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 3.93 MiB 3.92 MiB
GC Peak Live 95.64 MiB 82.15 MiB
GC Allocated During Run 13.97 GiB 10.09 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 2,813 2,659
GC Collected Objects 253,983,801 236,720,352
Heap Start Allocated 1.27 MiB 1.27 MiB
Heap End Allocated 1.27 MiB 1.27 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results

407 benchmarks

Interpreted: 🟢 73 improved · 🔴 55 regressed · 279 unchanged · avg +0.4%
Bytecode: 🟢 6 improved · 🔴 398 regressed · 3 unchanged · avg -26.1%

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

Deterministic profile diff

Deterministic profile diff: no significant changes.

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

@github-actions
Copy link
Copy Markdown
Contributor

test262 Conformance

Category Run Passed Δ Pass Failed Pass-rate Δ Rate
built-ins 23,449 16,067 +1 7,377 68.5% ±0pp
harness 116 72 ±0 44 62.1% ±0pp
intl402 3,324 892 ±0 2,432 26.8% ±0pp
language 23,635 14,203 ±0 9,432 60.1% ±0pp
staging 1,484 571 ±0 910 38.5% ±0pp
total 52,008 31,805 +1 20,195 61.2% ±0pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
built-ins/WeakMap 99.3% ±0pp 140 / 141
built-ins/WeakSet 98.8% ±0pp 84 / 85
language/future-reserved-words 98.1% ±0pp 53 / 54
Per-test deltas (+1 / -0)

Newly passing (1):

  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js

Steady-state failures are non-blocking; regressions vs the cached main baseline (lower total pass count, or any PASS → non-PASS transition) fail the conformance gate. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached main baseline.

@frostney frostney marked this pull request as ready for review May 20, 2026 20:53
@coderabbitai coderabbitai Bot added new feature New feature or request performance Performance improvement internal Refactoring, CI, tooling, cleanup labels May 20, 2026
@frostney frostney merged commit 741706b into main May 20, 2026
14 checks passed
@frostney frostney deleted the t3code/issue-596-fix branch May 20, 2026 21:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Refactoring, CI, tooling, cleanup new feature New feature or request performance Performance improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cache compiled RegExp program to eliminate per-match recompilation

1 participant