Skip to content

Add BigInt64Array and BigUint64Array support#365

Merged
frostney merged 4 commits intomainfrom
t3code/implement-bigint-typed-arrays
Apr 20, 2026
Merged

Add BigInt64Array and BigUint64Array support#365
frostney merged 4 commits intomainfrom
t3code/implement-bigint-typed-arrays

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 20, 2026

Summary

  • Adds BigInt64Array and BigUint64Array as supported typed array constructors and wires them into engine/runtime bootstrap registration.
  • Extends typed array element access and prototype methods to handle BigInt-backed arrays correctly, including fill, set, sort, includes, indexOf, map, filter, reduce, toReversed, toSorted, and with.
  • Enforces BigInt-specific type checks and error messages so BigInt typed arrays reject non-BigInt inputs.
  • Updates test262 harness and project documentation to reflect full typed array coverage.
  • Adds/expands typed array tests for BigInt constructor behavior and prototype operations.

- Add BigInt64Array and BigUint64Array constructors and runtime support
- Update TypedArray operations, harness helpers, docs, and tests
- Enforce BigInt-only element handling and mixed-type error paths
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 20, 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: 5d154281-028b-4ef7-9116-23182f4423c5

📥 Commits

Reviewing files that changed from the base of the PR and between 236535b and ca08d6a.

📒 Files selected for processing (1)
  • docs/decision-log.md

📝 Walkthrough

Walkthrough

Adds full BigInt typed-array support (BigInt64Array, BigUint64Array): new typed-array kinds, constructor registration and runtime BigInt plumbing, BigInt element read/write and validation, error/suggestion messages, test-harness updates, many new tests, and documentation/decision-log updates.

Changes

Cohort / File(s) Summary
Documentation
docs/built-ins-binary-data.md, docs/built-ins.md, docs/decision-log.md
Mark BigInt64Array/BigUint64Array as supported; update sizes/ranges table and add runtime decision entry for BigInt typed-array completion.
Constants & Messages
source/units/Goccia.Constants.ConstructorNames.pas, source/units/Goccia.Error.Messages.pas, source/units/Goccia.Error.Suggestions.pas
Add constructor name constants and resource strings for BigInt typed-array validation/errors and a suggestion message.
Engine & Runtime Registration
source/units/Goccia.Engine.pas, source/units/Goccia.Runtime.Bootstrap.pas
Register BigInt64Array/BigUint64Array constructors (kinds takBigInt64/takBigUint64) and introduce runtime field for the BigInt builtin with lifecycle handling.
Core TypedArray Implementation
source/units/Goccia.Values.TypedArrayValue.pas
Add enum kinds takBigInt64/takBigUint64; IsBigIntKind; BigInt element read/write helpers; centralized element conversion and BigInt-specific branches across constructors and most prototype methods; enforce BigInt-only assignments and reject mixing BigInt/non-BigInt typed arrays. (High-density functional changes.)
Test Harness
scripts/test262_harness/testTypedArray.js
Add bigIntArrayConstructors, extend allTypedArrayConstructors, implement harness helper for BigInt typed arrays, include BigInt kinds in atomics-friendly set.
Tests — Built-ins TypedArray
tests/built-ins/TypedArray/... (many files, e.g. constructors.js, element-access.js, from.js, of.js, prototype/*.js, prototype/toString-tag.js)
Add comprehensive Jest/Test262 tests parameterized for BigInt64Array and BigUint64Array covering construction, element access and type-rejection, and all prototype methods (iterators, callbacks, mutators, sort, set, slice, subarray, etc.).

Sequence Diagram(s)

sequenceDiagram
  participant Bootstrap as RuntimeBootstrap
  participant Engine as TGocciaEngine
  participant TAValue as TypedArrayValue
  participant Buffer as ArrayBuffer

  Bootstrap->>Engine: RegisterBuiltinConstructors()
  Engine->>Engine: register BigInt64Array / BigUint64Array (takBigInt64 / takBigUint64)
  Note over Engine,TAValue: Constructors reference TypedArrayValue kinds

  TAValue->>Buffer: CreateNativeInstance(length/ArrayBuffer)
  TAValue->>TAValue: Initialize elements (WriteBigIntElement / WriteValueToElement)
  User->>TAValue: ta[0] = 1n
  TAValue->>TAValue: Validate BigInt assignment (throw TypeError if not BigInt)
  User->>TAValue: v = ta[0]
  TAValue->>User: returns 1n (TGocciaBigIntValue)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

internal

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description includes a Summary section covering key implementation details and objectives. However, the Testing section of the template is not filled out with any checked items or descriptions of testing performed. Complete the Testing section by indicating which test verification items were completed (e.g., whether end-to-end tests were run, documentation was updated, regressions were verified).
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add BigInt64Array and BigUint64Array support' clearly and concisely summarizes the main change in the PR, which is the addition of support for these two BigInt-backed typed array constructors.
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 new feature New feature or request spec compliance Mismatch against official JavaScript/TypeScript specification labels Apr 20, 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: 5

🧹 Nitpick comments (10)
tests/built-ins/TypedArray/prototype/indexOf.js (1)

35-39: Add a mixed-type indexOf assertion for BigInt arrays.

A quick Number-vs-BigInt check here would guard against accidental coercion regressions.

Suggested test addition
   test.each([BigInt64Array, BigUint64Array])("%s indexOf", (TA) => {
     const ta = new TA([1n, 2n, 3n, 2n]);
     expect(ta.indexOf(2n)).toBe(1);
     expect(ta.indexOf(4n)).toBe(-1);
+    expect(ta.indexOf(2)).toBe(-1);
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/indexOf.js` around lines 35 - 39, Add a
mixed-type Number vs BigInt assertion to the existing BigInt typed-array indexOf
tests to ensure no coercion occurs: inside the test.each block that iterates
over BigInt64Array and BigUint64Array (the test using the local variable ta and
calling ta.indexOf), add an assertion that searching with a Number (e.g.,
ta.indexOf(2)) does not match the BigInt entry and returns -1, in addition to
the existing ta.indexOf(2n) and ta.indexOf(4n) checks.
tests/built-ins/TypedArray/prototype/filter.js (1)

41-47: Assert constructor preservation for filter result.
Current checks validate values but not that filter returns the same typed-array kind (TA), which is important in this PR scope.

Proposed test strengthening
   test.each([BigInt64Array, BigUint64Array])("%s filter", (TA) => {
     const ta = new TA([1n, 2n, 3n, 4n]);
     const filtered = ta.filter(x => x > 2n);
+    expect(filtered).toBeInstanceOf(TA);
     expect(filtered.length).toBe(2);
     expect(filtered[0]).toBe(3n);
     expect(filtered[1]).toBe(4n);
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/filter.js` around lines 41 - 47, The
test checks values from ta.filter but doesn't assert the result keeps the same
typed-array constructor; update the test in test.each (the TA/ta/filter/filtered
scope) to also assert that the filtered object's constructor equals the input TA
(or that filtered is an instance of TA) so the filtered result preserves the
TypedArray kind (e.g., add an expectation like filtered.constructor === TA or
expect(filtered instanceof TA)).
tests/built-ins/TypedArray/prototype/entries.js (1)

22-28: Add explicit second-index assertion for iterator tuples.
This makes the iterator ordering check more complete.

Proposed test strengthening
   test.each([BigInt64Array, BigUint64Array])("%s entries iterator", (TA) => {
     const ta = new TA([10n, 20n]);
     const entries = [...ta.entries()];
     expect(entries[0][0]).toBe(0);
     expect(entries[0][1]).toBe(10n);
+    expect(entries[1][0]).toBe(1);
     expect(entries[1][1]).toBe(20n);
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/entries.js` around lines 22 - 28, The
entries iterator test for BigInt64Array/BigUint64Array is missing an explicit
assertion for the second tuple's index; update the test (the test.each callback
that creates ta and entries) to assert the index of the second tuple as well
(i.e., add an expectation that entries[1][0] is 1) so both tuple index and value
positions are verified alongside the existing checks (entries[0][0],
entries[0][1], entries[1][1]).
tests/built-ins/TypedArray/prototype/copyWithin.js (1)

39-44: Consider asserting full post-copyWithin state.
Only checking indices 0/1 may miss BigInt-specific copy edge regressions in remaining positions.

Proposed test strengthening
   test.each([BigInt64Array, BigUint64Array])("%s copyWithin", (TA) => {
     const ta = new TA([1n, 2n, 3n, 4n, 5n]);
     ta.copyWithin(0, 3);
-    expect(ta[0]).toBe(4n);
-    expect(ta[1]).toBe(5n);
+    expect([...ta]).toEqual([4n, 5n, 3n, 4n, 5n]);
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/copyWithin.js` around lines 39 - 44, The
test currently only checks indices 0 and 1 after ta.copyWithin(0, 3) in the
test.each block; update the assertions to verify the entire TypedArray contents
for both BigInt64Array and BigUint64Array to catch regressions—after calling
ta.copyWithin(0, 3) assert that the full array equals [4n, 5n, 3n, 4n, 5n] (use
Array.from(ta) or an equivalent full-array comparison) so the TA variable and
the copyWithin behavior are fully validated.
tests/built-ins/TypedArray/prototype/subarray.js (1)

47-55: Consider also asserting shared-buffer aliasing for BigInt subarrays.

Current assertions validate values and length, but not the key subarray aliasing behavior already checked in Lines 2-10 for Int32Array.

➕ Optional assertion
   test.each([BigInt64Array, BigUint64Array])("%s subarray", (TA) => {
@@
     expect(sub.length).toBe(2);
     expect(sub[0]).toBe(20n);
     expect(sub[1]).toBe(30n);
+    ta[1] = 99n;
+    expect(sub[0]).toBe(99n);
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/subarray.js` around lines 47 - 55, Add
an assertion that the subarray shares the same underlying buffer as the original
typed array to verify aliasing: in the test.each block for BigInt64Array and
BigUint64Array, after creating ta and sub (using ta.subarray(1, 3)), assert that
sub.buffer === ta.buffer (and optionally that modifying ta[...] changes sub[...]
or vice versa) so the BigInt typed arrays confirm the same shared-buffer
behavior checked earlier for Int32Array.
tests/built-ins/TypedArray/prototype/toString-tag.js (1)

36-44: Prefer adding BigInt constructors to the shared matrix.

These standalone tests cover only Object.prototype.toString, but skip the shared accessor checks already run for other typed arrays. Folding BigInt constructors into constructors gives fuller coverage with less duplication.

♻️ Suggested refactor
   const constructors = [
@@
     [Float32Array, "[object Float32Array]"],
     [Float64Array, "[object Float64Array]"],
+    [BigInt64Array, "[object BigInt64Array]"],
+    [BigUint64Array, "[object BigUint64Array]"],
   ];
@@
-  test("BigInt64Array toStringTag", () => {
-    const ta = new BigInt64Array(0);
-    expect(Object.prototype.toString.call(ta)).toBe("[object BigInt64Array]");
-  });
-
-  test("BigUint64Array toStringTag", () => {
-    const ta = new BigUint64Array(0);
-    expect(Object.prototype.toString.call(ta)).toBe("[object BigUint64Array]");
-  });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/toString-tag.js` around lines 36 - 44,
Add BigInt64Array and BigUint64Array to the shared constructors matrix used by
the existing typed-array test suite instead of keeping these as standalone
tests; locate the constructors array/matrix (named like constructors or the
shared "constructors" matrix used by the other typed-array tests) and append
BigInt64Array and BigUint64Array so they run through the same shared accessor
and toStringTag checks, then remove or convert the two standalone tests in
tests/built-ins/TypedArray/prototype/toString-tag.js to avoid duplication.
tests/built-ins/TypedArray/prototype/sort.js (1)

82-88: Assert comparator arguments are BigInt values.

Current assertions validate order, but not callback argument type. Adding typeof checks in comparefn will catch accidental Number coercion regressions.

Proposed test adjustment
-      ta.sort((a, b) => (a > b ? -1 : a < b ? 1 : 0));
+      ta.sort((a, b) => {
+        expect(typeof a).toBe("bigint");
+        expect(typeof b).toBe("bigint");
+        return a > b ? -1 : a < b ? 1 : 0;
+      });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/sort.js` around lines 82 - 88, The test
"sort with comparefn" should also assert that the comparator receives BigInt
arguments to catch accidental Number coercion; update the compare function
passed to TA.prototype.sort (the callback inside the test using ta.sort((a, b)
=> ...)) to include typeof checks for a and b being "bigint" (e.g., assert or
expect that typeof a === "bigint" and typeof b === "bigint") before performing
the comparison and returning -1/1/0, ensuring the test both verifies ordering
and the argument types.
tests/built-ins/TypedArray/from.js (1)

42-56: Add rejection-path coverage for BigInt-only coercion.

These tests cover valid BigInt inputs well, but they don’t assert TypeError for non-BigInt sources/mapFn results (e.g., TA.from([1,2,3]), TA.from([1n], () => 1)). Adding those will protect the new type-check behavior from regressions.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/from.js` around lines 42 - 56, Add tests that
assert TypeError is thrown when BigInt-only typed arrays receive non-BigInt
inputs or when the mapping function returns non-BigInt values: for the existing
describe.each over BigInt64Array and BigUint64Array, add cases calling
TA.from([1,2,3]) and expecting a TypeError, and a case calling TA.from([1n], ()
=> 1) (and similar variations) and expecting a TypeError; place these alongside
the existing ".from array of BigInts" and ".from with mapFn" tests so TA.from
and the mapFn behavior are covered for rejection paths.
source/units/Goccia.Engine.pas (1)

962-973: Consider centralizing typed-array constructor registration to avoid drift.

This constructor list is duplicated in source/units/Goccia.Runtime.Bootstrap.pas (Lines 435-446). A shared helper would reduce future mismatch risk when adding/removing typed-array kinds.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@source/units/Goccia.Engine.pas` around lines 962 - 973, The typed-array
constructor registrations (calls to RegisterTypedArrayConstructor for
CONSTRUCTOR_INT8_ARRAY, CONSTRUCTOR_UINT8_ARRAY,
CONSTRUCTOR_UINT8_CLAMPED_ARRAY, CONSTRUCTOR_INT16_ARRAY,
CONSTRUCTOR_UINT16_ARRAY, CONSTRUCTOR_INT32_ARRAY, CONSTRUCTOR_UINT32_ARRAY,
CONSTRUCTOR_FLOAT16_ARRAY, CONSTRUCTOR_FLOAT32_ARRAY, CONSTRUCTOR_FLOAT64_ARRAY,
CONSTRUCTOR_BIGINT64_ARRAY, CONSTRUCTOR_BIGUINT64_ARRAY) are duplicated across
units (e.g., Goccia.Engine and Goccia.Runtime.Bootstrap); extract them into a
single shared routine (e.g., RegisterAllTypedArrayConstructors or
RegisterDefaultTypedArrayConstructors) in a common unit and replace the
duplicated blocks by calling that helper from both places so future
additions/removals are centralized and cannot drift.
tests/built-ins/TypedArray/constructors.js (1)

234-282: Add upper-half and mixed-kind regression cases.

These tests only exercise small signed-safe values, so they won't catch two easy failure modes here: BigUint64Array values above 2^63 - 1, and the required TypeError when copying between BigInt-backed and Number-backed typed arrays. A couple of cases around 18446744073709551615n, -1n, and new BigInt64Array(new Int32Array([1])) / .set(new Int32Array([1])) would lock those down.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/constructors.js` around lines 234 - 282, Add
regression tests that cover large unsigned values and mixed-kind copies: add
cases creating BigUint64Array with values above 2^63-1 (e.g.,
18446744073709551615n) and BigInt64Array with negative values like -1n to ensure
correct representation, and add tests that copying between BigInt-backed arrays
and Number-backed arrays (e.g., new BigInt64Array(new Int32Array([1])) and
calling .set(new Int32Array([1]))) throws a TypeError; update the test block
around the BigInt64Array/BigUint64Array constructors and the "shares underlying
buffer" section to include these new cases so BigUint64Array, BigInt64Array, and
their .set/copy behavior are validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/decision-log.md`:
- Line 20: Remove the duplicated word in the new decision-log entry by replacing
the phrase "BigInt-typed typed array constructors" with "BigInt-typed array
constructors" in the entry that starts with "**2026-04-20** · `runtime` —
BigInt64Array/BigUint64Array (ES2020)"; ensure the rest of the sentence and the
link to [built-ins-binary-data.md] remain unchanged.

In `@source/units/Goccia.Runtime.Bootstrap.pas`:
- Around line 445-446: Register the BigInt global constructor alongside the
BigInt typed-array registrations: add a registration call for
TGocciaGlobalBigInt (the same pattern used for other globals) near the two
RegisterTypedArrayConstructor calls for CONSTRUCTOR_BIGINT64_ARRAY and
CONSTRUCTOR_BIGUINT64_ARRAY so bootstrap exposes BigInt() at runtime; implement
it using the same constructor handler used elsewhere (e.g., ObjectConstructor)
and the matching constructor identifier (e.g., CONSTRUCTOR_BIGINT) so behavior
matches the TGocciaGlobalBigInt registration in the engine unit.

In `@source/units/Goccia.Values.TypedArrayValue.pas`:
- Around line 1067-1108: The code treats BigUint64Array elements as signed by
using TA.ReadBigIntElement with TBigInteger.FromInt64 when building
comparator/callback args and in the default comparator; replace those usages
with the existing GetElementAsValue(...) (which applies BigIntFromQWord for
takBigUint64) when creating TGocciaBigIntValue arguments for Call, and for the
default comparison branch (where it currently compares TA.ReadBigIntElement(...)
to TmpBig) implement an unsigned-aware comparison when FKind = takBigUint64
(compare raw QWord/UInt64 representations or use BigIntFromQWord for both
operands) so values >= 2^63 are handled correctly; update the same pattern in
the corresponding block around lines 1551-1569 as well.
- Around line 1999-2017: Remove the BigInt-special branch: delete the "if
FirstArg is TGocciaBigIntValue then ..." block and instead always call
FirstArg.ToNumberLiteral (as the code already does in the else branch) to obtain
Num; preserve the existing NaN/truncation/negative-length checks and
ThrowRangeError calls (SErrorInvalidTypedArrayLength, SSuggestTypedArrayLength).
This ensures ToNumber is applied to FirstArg (causing BigInt to raise TypeError)
per ES2026 §23.2.1.2 and avoids extracting a BigInt via
TGocciaBigIntValue.ToInt64.
- Around line 793-809: The fill()/with() implementation is incorrectly
hardcoding omitted value to zero; instead, when AArgs.Length = 0 you must coerce
undefined through the normal conversion path (so BigInt kinds throw via the
TGocciaBigIntValue check and numeric kinds preserve NaN behavior), so remove the
special-case assignments (FillBigInt := 0 and FillNum :=
TGocciaNumberLiteralValue.ZeroValue) and let the code call the existing
type-check/coercion logic: for bigints keep the TGocciaBigIntValue type
assertion and ThrowTypeError using
SErrorBigIntTypedArrayRequiresBigInt/SSuggestBigIntTypedArrayValue, and for
numbers call AArgs.GetElement(0).ToNumberLiteral (or pass the absent element
through the same ToNumberLiteral/conversion flow) so undefined is coerced
normally; apply the same change in the with() implementation referenced around
line 1782.

---

Nitpick comments:
In `@source/units/Goccia.Engine.pas`:
- Around line 962-973: The typed-array constructor registrations (calls to
RegisterTypedArrayConstructor for CONSTRUCTOR_INT8_ARRAY,
CONSTRUCTOR_UINT8_ARRAY, CONSTRUCTOR_UINT8_CLAMPED_ARRAY,
CONSTRUCTOR_INT16_ARRAY, CONSTRUCTOR_UINT16_ARRAY, CONSTRUCTOR_INT32_ARRAY,
CONSTRUCTOR_UINT32_ARRAY, CONSTRUCTOR_FLOAT16_ARRAY, CONSTRUCTOR_FLOAT32_ARRAY,
CONSTRUCTOR_FLOAT64_ARRAY, CONSTRUCTOR_BIGINT64_ARRAY,
CONSTRUCTOR_BIGUINT64_ARRAY) are duplicated across units (e.g., Goccia.Engine
and Goccia.Runtime.Bootstrap); extract them into a single shared routine (e.g.,
RegisterAllTypedArrayConstructors or RegisterDefaultTypedArrayConstructors) in a
common unit and replace the duplicated blocks by calling that helper from both
places so future additions/removals are centralized and cannot drift.

In `@tests/built-ins/TypedArray/constructors.js`:
- Around line 234-282: Add regression tests that cover large unsigned values and
mixed-kind copies: add cases creating BigUint64Array with values above 2^63-1
(e.g., 18446744073709551615n) and BigInt64Array with negative values like -1n to
ensure correct representation, and add tests that copying between BigInt-backed
arrays and Number-backed arrays (e.g., new BigInt64Array(new Int32Array([1]))
and calling .set(new Int32Array([1]))) throws a TypeError; update the test block
around the BigInt64Array/BigUint64Array constructors and the "shares underlying
buffer" section to include these new cases so BigUint64Array, BigInt64Array, and
their .set/copy behavior are validated.

In `@tests/built-ins/TypedArray/from.js`:
- Around line 42-56: Add tests that assert TypeError is thrown when BigInt-only
typed arrays receive non-BigInt inputs or when the mapping function returns
non-BigInt values: for the existing describe.each over BigInt64Array and
BigUint64Array, add cases calling TA.from([1,2,3]) and expecting a TypeError,
and a case calling TA.from([1n], () => 1) (and similar variations) and expecting
a TypeError; place these alongside the existing ".from array of BigInts" and
".from with mapFn" tests so TA.from and the mapFn behavior are covered for
rejection paths.

In `@tests/built-ins/TypedArray/prototype/copyWithin.js`:
- Around line 39-44: The test currently only checks indices 0 and 1 after
ta.copyWithin(0, 3) in the test.each block; update the assertions to verify the
entire TypedArray contents for both BigInt64Array and BigUint64Array to catch
regressions—after calling ta.copyWithin(0, 3) assert that the full array equals
[4n, 5n, 3n, 4n, 5n] (use Array.from(ta) or an equivalent full-array comparison)
so the TA variable and the copyWithin behavior are fully validated.

In `@tests/built-ins/TypedArray/prototype/entries.js`:
- Around line 22-28: The entries iterator test for BigInt64Array/BigUint64Array
is missing an explicit assertion for the second tuple's index; update the test
(the test.each callback that creates ta and entries) to assert the index of the
second tuple as well (i.e., add an expectation that entries[1][0] is 1) so both
tuple index and value positions are verified alongside the existing checks
(entries[0][0], entries[0][1], entries[1][1]).

In `@tests/built-ins/TypedArray/prototype/filter.js`:
- Around line 41-47: The test checks values from ta.filter but doesn't assert
the result keeps the same typed-array constructor; update the test in test.each
(the TA/ta/filter/filtered scope) to also assert that the filtered object's
constructor equals the input TA (or that filtered is an instance of TA) so the
filtered result preserves the TypedArray kind (e.g., add an expectation like
filtered.constructor === TA or expect(filtered instanceof TA)).

In `@tests/built-ins/TypedArray/prototype/indexOf.js`:
- Around line 35-39: Add a mixed-type Number vs BigInt assertion to the existing
BigInt typed-array indexOf tests to ensure no coercion occurs: inside the
test.each block that iterates over BigInt64Array and BigUint64Array (the test
using the local variable ta and calling ta.indexOf), add an assertion that
searching with a Number (e.g., ta.indexOf(2)) does not match the BigInt entry
and returns -1, in addition to the existing ta.indexOf(2n) and ta.indexOf(4n)
checks.

In `@tests/built-ins/TypedArray/prototype/sort.js`:
- Around line 82-88: The test "sort with comparefn" should also assert that the
comparator receives BigInt arguments to catch accidental Number coercion; update
the compare function passed to TA.prototype.sort (the callback inside the test
using ta.sort((a, b) => ...)) to include typeof checks for a and b being
"bigint" (e.g., assert or expect that typeof a === "bigint" and typeof b ===
"bigint") before performing the comparison and returning -1/1/0, ensuring the
test both verifies ordering and the argument types.

In `@tests/built-ins/TypedArray/prototype/subarray.js`:
- Around line 47-55: Add an assertion that the subarray shares the same
underlying buffer as the original typed array to verify aliasing: in the
test.each block for BigInt64Array and BigUint64Array, after creating ta and sub
(using ta.subarray(1, 3)), assert that sub.buffer === ta.buffer (and optionally
that modifying ta[...] changes sub[...] or vice versa) so the BigInt typed
arrays confirm the same shared-buffer behavior checked earlier for Int32Array.

In `@tests/built-ins/TypedArray/prototype/toString-tag.js`:
- Around line 36-44: Add BigInt64Array and BigUint64Array to the shared
constructors matrix used by the existing typed-array test suite instead of
keeping these as standalone tests; locate the constructors array/matrix (named
like constructors or the shared "constructors" matrix used by the other
typed-array tests) and append BigInt64Array and BigUint64Array so they run
through the same shared accessor and toStringTag checks, then remove or convert
the two standalone tests in tests/built-ins/TypedArray/prototype/toString-tag.js
to avoid duplication.
🪄 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: 220b8515-70ea-47e9-809a-39089841ce0a

📥 Commits

Reviewing files that changed from the base of the PR and between 9870f9f and 17c8de8.

📒 Files selected for processing (43)
  • docs/built-ins-binary-data.md
  • docs/built-ins.md
  • docs/decision-log.md
  • scripts/test262_harness/testTypedArray.js
  • source/units/Goccia.Constants.ConstructorNames.pas
  • source/units/Goccia.Engine.pas
  • source/units/Goccia.Error.Messages.pas
  • source/units/Goccia.Error.Suggestions.pas
  • source/units/Goccia.Runtime.Bootstrap.pas
  • source/units/Goccia.Values.TypedArrayValue.pas
  • tests/built-ins/TypedArray/constructors.js
  • tests/built-ins/TypedArray/element-access.js
  • tests/built-ins/TypedArray/from.js
  • tests/built-ins/TypedArray/of.js
  • tests/built-ins/TypedArray/prototype/at.js
  • tests/built-ins/TypedArray/prototype/copyWithin.js
  • tests/built-ins/TypedArray/prototype/entries.js
  • tests/built-ins/TypedArray/prototype/every.js
  • tests/built-ins/TypedArray/prototype/fill.js
  • tests/built-ins/TypedArray/prototype/filter.js
  • tests/built-ins/TypedArray/prototype/find.js
  • tests/built-ins/TypedArray/prototype/findIndex.js
  • tests/built-ins/TypedArray/prototype/findLast.js
  • tests/built-ins/TypedArray/prototype/findLastIndex.js
  • tests/built-ins/TypedArray/prototype/forEach.js
  • tests/built-ins/TypedArray/prototype/includes.js
  • tests/built-ins/TypedArray/prototype/indexOf.js
  • tests/built-ins/TypedArray/prototype/join.js
  • tests/built-ins/TypedArray/prototype/lastIndexOf.js
  • tests/built-ins/TypedArray/prototype/map.js
  • tests/built-ins/TypedArray/prototype/reduce.js
  • tests/built-ins/TypedArray/prototype/reduceRight.js
  • tests/built-ins/TypedArray/prototype/reverse.js
  • tests/built-ins/TypedArray/prototype/set.js
  • tests/built-ins/TypedArray/prototype/slice.js
  • tests/built-ins/TypedArray/prototype/some.js
  • tests/built-ins/TypedArray/prototype/sort.js
  • tests/built-ins/TypedArray/prototype/subarray.js
  • tests/built-ins/TypedArray/prototype/toReversed.js
  • tests/built-ins/TypedArray/prototype/toSorted.js
  • tests/built-ins/TypedArray/prototype/toString-tag.js
  • tests/built-ins/TypedArray/prototype/values.js
  • tests/built-ins/TypedArray/prototype/with.js

Comment thread docs/decision-log.md Outdated
Comment thread source/units/Goccia.Runtime.Bootstrap.pas
Comment thread source/units/Goccia.Values.TypedArrayValue.pas
Comment thread source/units/Goccia.Values.TypedArrayValue.pas
Comment thread source/units/Goccia.Values.TypedArrayValue.pas Outdated
frostney and others added 2 commits April 20, 2026 13:44
…nt-typed-arrays

# Conflicts:
#	docs/decision-log.md
- Fix duplicated word in decision-log entry
- Register BigInt global constructor in Bootstrap for parity
- Fix fill()/with() to throw TypeError when value omitted on BigInt arrays
  (coerce undefined per ES spec instead of hardcoding zero)
- Fix BigUint64Array signedness: sort comparator and filter callback now
  use unsigned-aware logic for values >= 2^63
- Remove BigInt special case from TypedArray length constructor; ToNumber
  correctly throws TypeError for BigInt per ES2026 §7.1.4
- Enforce TypeError on set() when mixing BigInt/Number typed arrays
- Strengthen tests: mixed-type indexOf, constructor preservation, entries
  index, full copyWithin state, subarray aliasing, sort typeof checks,
  from() rejection paths, upper-half BigUint64 values, toStringTag matrix

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
docs/decision-log.md (1)

20-21: Add the PR link for decision-trace consistency.

The new entry is clear, but it would be easier to audit later if it also includes [#365](https://github.com/frostney/GocciaScript/pull/365), consistent with nearby entries that link both PR and docs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/decision-log.md` around lines 20 - 21, Update the 2026-04-20 runtime
entry for BigInt64Array/BigUint64Array in decision-log.md to include the PR link
for traceability: append "
[`#365`](https://github.com/frostney/GocciaScript/pull/365)" to the end of the
existing bullet (the entry that starts with "2026-04-20 · `runtime` —
BigInt64Array/BigUint64Array (ES2020)"), matching surrounding entries' format so
both the docs link and PR number are present for that line.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@docs/decision-log.md`:
- Around line 20-21: Update the 2026-04-20 runtime entry for
BigInt64Array/BigUint64Array in decision-log.md to include the PR link for
traceability: append "
[`#365`](https://github.com/frostney/GocciaScript/pull/365)" to the end of the
existing bullet (the entry that starts with "2026-04-20 · `runtime` —
BigInt64Array/BigUint64Array (ES2020)"), matching surrounding entries' format so
both the docs link and PR number are present for that line.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1c4a1722-ec9c-49a2-bf06-fc8792cd1c23

📥 Commits

Reviewing files that changed from the base of the PR and between 17c8de8 and 236535b.

📒 Files selected for processing (14)
  • docs/decision-log.md
  • source/units/Goccia.Engine.pas
  • source/units/Goccia.Error.Messages.pas
  • source/units/Goccia.Runtime.Bootstrap.pas
  • source/units/Goccia.Values.TypedArrayValue.pas
  • tests/built-ins/TypedArray/constructors.js
  • tests/built-ins/TypedArray/from.js
  • tests/built-ins/TypedArray/prototype/copyWithin.js
  • tests/built-ins/TypedArray/prototype/entries.js
  • tests/built-ins/TypedArray/prototype/filter.js
  • tests/built-ins/TypedArray/prototype/indexOf.js
  • tests/built-ins/TypedArray/prototype/sort.js
  • tests/built-ins/TypedArray/prototype/subarray.js
  • tests/built-ins/TypedArray/prototype/toString-tag.js
✅ Files skipped from review due to trivial changes (8)
  • tests/built-ins/TypedArray/prototype/filter.js
  • tests/built-ins/TypedArray/prototype/indexOf.js
  • tests/built-ins/TypedArray/prototype/entries.js
  • tests/built-ins/TypedArray/prototype/subarray.js
  • tests/built-ins/TypedArray/prototype/toString-tag.js
  • tests/built-ins/TypedArray/prototype/sort.js
  • tests/built-ins/TypedArray/constructors.js
  • source/units/Goccia.Error.Messages.pas
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/built-ins/TypedArray/from.js
  • source/units/Goccia.Engine.pas
  • tests/built-ins/TypedArray/prototype/copyWithin.js
  • source/units/Goccia.Runtime.Bootstrap.pas
  • source/units/Goccia.Values.TypedArrayValue.pas

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 20, 2026

Benchmark Results

386 benchmarks

Interpreted: 🟢 386 improved · avg +33.4%
Bytecode: 🟢 225 improved · 🔴 59 regressed · 102 unchanged · avg +3.2%

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

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 20, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 5936 5936
Tests Passed 5895 ✅ 5936 ✅
Tests Skipped 41 0
Tests Workers 4 4
Tests Test Duration 1.30s 1.40s
Tests Lex (cumulative) 186.2ms 122.3ms
Tests Parse (cumulative) 256.5ms 243.3ms
Tests Compile (cumulative) 161.7ms
Tests Execute (cumulative) 1.24s 1.48s
Tests Engine Total (cumulative) 1.69s 2.00s
Tests Lex (avg/worker) 46.6ms 30.6ms
Tests Parse (avg/worker) 64.1ms 60.8ms
Tests Compile (avg/worker) 40.4ms
Tests Execute (avg/worker) 311.0ms 369.3ms
Tests Engine Total (avg/worker) 421.6ms 501.1ms
Benchmarks Total 386 386
Benchmarks Workers 4 4
Benchmarks Duration 3.24min 2.90min

Measured on ubuntu-latest x64.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai coderabbitai Bot added the internal Refactoring, CI, tooling, cleanup label Apr 20, 2026
@frostney frostney merged commit cd6282b into main Apr 20, 2026
10 checks passed
@frostney frostney deleted the t3code/implement-bigint-typed-arrays branch April 20, 2026 13:15
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 spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant