Skip to content

Fix property redefinition rules for objects and arrays#381

Merged
frostney merged 2 commits into
mainfrom
t3code/verify-implement-376
Apr 22, 2026
Merged

Fix property redefinition rules for objects and arrays#381
frostney merged 2 commits into
mainfrom
t3code/verify-implement-376

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 21, 2026

Summary

  • Tightened Object.defineProperty and Reflect.defineProperty handling for non-configurable properties to follow ES2026 compatibility rules.
  • Added shared descriptor validation for ordinary objects and symbol properties, including data/accessor transitions and writable/value constraints.
  • Implemented array-specific defineProperty behavior for length and numeric indices, including truncation, विस्तार, and hole filling.
  • Added regression tests covering allowed and rejected redefinitions on objects, arrays, and Reflect.defineProperty boolean results.

Fixes #376

- validate non-configurable descriptors before redefining
- handle array length and indexed defineProperty updates
- add coverage for Object.defineProperty and Reflect.defineProperty
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f9ebb77b-6752-4ac1-8374-e80c3c5b7f47

📥 Commits

Reviewing files that changed from the base of the PR and between e3536f3 and 8a6e174.

📒 Files selected for processing (4)
  • source/units/Goccia.VM.pas
  • source/units/Goccia.Values.ArrayValue.pas
  • source/units/Goccia.Values.ObjectValue.pas
  • tests/built-ins/Object/defineProperty.js
✅ Files skipped from review due to trivial changes (2)
  • tests/built-ins/Object/defineProperty.js
  • source/units/Goccia.Values.ArrayValue.pas

📝 Walkthrough

Walkthrough

Implements ES spec-compliant property descriptor validation for non-configurable property redefinitions. Adds array-specific defineProperty handling for length and numeric indices. Updates validation logic in core object/array value classes and includes comprehensive test coverage.

Changes

Cohort / File(s) Summary
Array & Object property definition
source/units/Goccia.Values.ArrayValue.pas, source/units/Goccia.Values.ObjectValue.pas
Adds DefineProperty/TryDefineProperty overrides to TGocciaArrayValue for length and numeric index handling. Updates TGocciaObjectValue methods with centralized ValidatePropertyDescriptor logic implementing ES spec compatibility rules for non-configurable redefinitions (rejects enumerable/kind/accessor changes; allows value changes if writable; prevents writable falsetrue). Adjusts descriptor ownership semantics and validation/freeing behavior across DefineProperty, TryDefineProperty, DefineSymbolProperty, and TryDefineSymbolProperty.
VM enumeration finalization
source/units/Goccia.VM.pas
Reorders call sequence in FinalizeEnumValue so InitializeEnumSymbols executes before PreventExtensions.
Property definition test suite
tests/built-ins/Object/defineProperty.js
Adds 268 lines of test cases covering non-configurable property redefinition rules (allowed updates: value changes when writable, writable truefalse; forbidden: enumerable/kind/accessor changes), configurable transitions, descriptor flag preservation, Reflect.defineProperty return values, and array-specific length truncation/extension/numeric index interactions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix property redefinition rules for objects and arrays' directly and concisely describes the main objective of the changeset: implementing proper property redefinition validation for both objects and arrays according to ES2026 spec rules.
Description check ✅ Passed The PR description covers the summary, links the related issue (#376), and provides implementation details. All checklist items in the template are addressed or marked as N/A.
Linked Issues check ✅ Passed All four coding objectives from issue #376 are addressed: (1) non-configurable property redefinition rules via ValidatePropertyDescriptor [ObjectValue.pas], (2) array length/index interaction via TryDefineProperty overrides [ArrayValue.pas], (3) data↔accessor transitions now allowed when configurable [ObjectValue.pas, tests], (4) descriptor flag preservation via proper inheritance logic [ObjectValue.pas].
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #376: object/array property redefinition validation, descriptor compatibility checks, array length handling, enum symbol initialization order fix for test compatibility, and comprehensive regression tests. No unrelated modifications 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.

@coderabbitai coderabbitai Bot added bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification labels Apr 21, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
tests/built-ins/Object/defineProperty-array.js (1)

1-61: Good test coverage for array-specific defineProperty behavior.

The tests comprehensively cover:

  • Length truncation, extension, and zeroing
  • Numeric index updates within and beyond current bounds
  • Non-index property handling

Consider adding edge-case tests for invalid length values (NaN, Infinity, non-integer, negative) to validate proper RangeError handling.

Optional: Add edge-case tests for invalid lengths
test("defineProperty on array length with NaN throws", () => {
  const arr = [1, 2, 3];
  expect(() => {
    Object.defineProperty(arr, "length", { value: NaN });
  }).toThrow();
});

test("defineProperty on array length with negative throws", () => {
  const arr = [1, 2, 3];
  expect(() => {
    Object.defineProperty(arr, "length", { value: -1 });
  }).toThrow();
});

test("defineProperty on array length with non-integer throws", () => {
  const arr = [1, 2, 3];
  expect(() => {
    Object.defineProperty(arr, "length", { value: 1.5 });
  }).toThrow();
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/Object/defineProperty-array.js` around lines 1 - 61, Add
edge-case tests to validate that Object.defineProperty on an array "length"
correctly throws RangeError for invalid length values; specifically add tests
using Object.defineProperty(arr, "length", { value: NaN }), value: Infinity,
value: -1, and a non-integer like 1.5 (or similar) and assert they throw (or
throw RangeError) to complement existing tests in
tests/built-ins/Object/defineProperty-array.js; reference the existing tests by
pattern/name (e.g., the "defineProperty on array length ..." tests) and ensure
each new test follows the same test(...) structure and expectations.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@source/units/Goccia.Values.ArrayValue.pas`:
- Around line 1783-1790: The current TryDefineProperty branch that handles
TGocciaPropertyDescriptorData only checks NewLen < 0; update it to mirror the
constructor's ES2026 §10.4.2.4 validation: obtain the numeric Len from
TGocciaPropertyDescriptorData(ADescriptor).Value.ToNumberLiteral.Value into
NewLen, then reject and return False if NewLen is NaN or infinite, if NewLen <>
Trunc(NewLen) (non-integer), or if NewLen > 4294967295 (overflow); when
rejecting free ADescriptor and Exit(False) as already done for negative values
so the behavior matches the constructor's validation.

In `@source/units/Goccia.Values.ObjectValue.pas`:
- Around line 716-717: The branch that handles adding a property when the object
is not extensible uses the wrong error token; update the ThrowTypeError call in
the block checking FExtensible to use SErrorCannotAddPropertyNotExtensible
instead of SErrorCannotRedefineNonConfigurable (keep the same Format([AName])
and suggestion SSuggestCannotDeleteNonConfigurable). Locate the code path where
FExtensible is tested (the else if not FExtensible branch) and replace the error
identifier so the thrown error correctly indicates adding a property to a
non‑extensible object.
- Around line 981-982: The error raised when adding a new symbol property on a
non-extensible object uses the wrong message constant; in the else branch that
checks FExtensible and calls
ThrowTypeError(Format(SErrorCannotRedefineNonConfigurable,
[ASymbol.ToDisplayString.Value]), SSuggestCannotDeleteNonConfigurable) replace
the message constant with the symbol-specific one (e.g.,
SErrorCannotAddSymbolNotExtensible) and adjust the suggestion constant if needed
so the thrown error refers to adding a symbol on a non-extensible object (refer
to FExtensible, ThrowTypeError, ASymbol.ToDisplayString.Value,
SErrorCannotRedefineNonConfigurable).

---

Nitpick comments:
In `@tests/built-ins/Object/defineProperty-array.js`:
- Around line 1-61: Add edge-case tests to validate that Object.defineProperty
on an array "length" correctly throws RangeError for invalid length values;
specifically add tests using Object.defineProperty(arr, "length", { value: NaN
}), value: Infinity, value: -1, and a non-integer like 1.5 (or similar) and
assert they throw (or throw RangeError) to complement existing tests in
tests/built-ins/Object/defineProperty-array.js; reference the existing tests by
pattern/name (e.g., the "defineProperty on array length ..." tests) and ensure
each new test follows the same test(...) structure and expectations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: be76dd75-0b9a-4e61-9cc0-ef875b7a80d5

📥 Commits

Reviewing files that changed from the base of the PR and between 99fba02 and e3536f3.

📒 Files selected for processing (4)
  • source/units/Goccia.Values.ArrayValue.pas
  • source/units/Goccia.Values.ObjectValue.pas
  • tests/built-ins/Object/defineProperty-array.js
  • tests/built-ins/Object/defineProperty-redefinition.js

Comment thread source/units/Goccia.Values.ArrayValue.pas
Comment thread source/units/Goccia.Values.ObjectValue.pas Outdated
Comment thread source/units/Goccia.Values.ObjectValue.pas Outdated
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 21, 2026

Benchmark Results

386 benchmarks

Interpreted: 🟢 15 improved · 🔴 324 regressed · 47 unchanged · avg -7.2%
Bytecode: 🟢 85 improved · 🔴 52 regressed · 249 unchanged · avg +0.9%

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

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

github-actions Bot commented Apr 21, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 7548 7548
Tests Passed 7507 ✅ 7548 ✅
Tests Skipped 41 0
Tests Workers 4 4
Tests Test Duration 1.50s 1.50s
Tests Lex (cumulative) 191.9ms 118.3ms
Tests Parse (cumulative) 292.4ms 255.2ms
Tests Compile (cumulative) 174.5ms
Tests Execute (cumulative) 1.64s 1.52s
Tests Engine Total (cumulative) 2.12s 2.07s
Tests Lex (avg/worker) 48.0ms 29.6ms
Tests Parse (avg/worker) 73.1ms 63.8ms
Tests Compile (avg/worker) 43.6ms
Tests Execute (avg/worker) 409.0ms 379.7ms
Tests Engine Total (avg/worker) 530.1ms 516.7ms
Benchmarks Total 386 386
Benchmarks Workers 4 4
Benchmarks Duration 2.93min 2.72min

Measured on ubuntu-latest x64.

- Fix VM FinalizeEnumValue to initialize symbols before PreventExtensions
  (matches interpreted mode order, fixes 30 bytecode enum test failures)
- Use correct error messages for non-extensible objects in DefineProperty
  (SErrorCannotAddPropertyNotExtensible / SErrorCannotAddSymbolNotExtensible)
- Add array length validation for NaN, non-integer, and overflow values
- Consolidate tests into single defineProperty.js file

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@frostney frostney merged commit 310fb3e into main Apr 22, 2026
10 checks passed
@frostney frostney deleted the t3code/verify-implement-376 branch April 22, 2026 21:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Object.defineProperty: non-configurable redefine rules and array length interaction

1 participant