Skip to content

Expand typed array coverage across core methods#367

Merged
frostney merged 4 commits intomainfrom
t3code/8b9d2d47
Apr 20, 2026
Merged

Expand typed array coverage across core methods#367
frostney merged 4 commits intomainfrom
t3code/8b9d2d47

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 20, 2026

Summary

  • Added broad coverage for TypedArray constructors and prototype methods across numeric typed arrays.
  • Included tests for common behaviors like iteration, searching, mutation, copying, sorting, and conversion helpers.
  • Added @@toStringTag assertions for all typed array variants, including BigInt typed arrays.

- Add broader TypedArray coverage for constructors and prototype methods
- Include numeric, iterator, mutation, and copy semantics checks
@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: 071532f4-5d64-4784-ae0b-f4153cd05bde

📥 Commits

Reviewing files that changed from the base of the PR and between f88825a and d33c51a.

📒 Files selected for processing (3)
  • tests/built-ins/TypedArray/prototype/find.js
  • tests/built-ins/TypedArray/prototype/keys.js
  • tests/built-ins/TypedArray/prototype/toReversed.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/built-ins/TypedArray/prototype/find.js
  • tests/built-ins/TypedArray/prototype/keys.js

📝 Walkthrough

Walkthrough

Generalizes many TypedArray tests from Int32Array-specific cases to parameterized describe.each suites that run the same assertions across numeric TypedArray constructors (Int8Array … Float64Array). Preserves BigInt typed-array blocks and updates Pascal runtime sorting to discriminate -0 vs +0 for float typed arrays.

Changes

Cohort / File(s) Summary
TypedArray static factories
tests/built-ins/TypedArray/from.js, tests/built-ins/TypedArray/of.js
Replaced Int32Array-specific from/of tests with parameterized describe.each over numeric TypedArray constructors; empty-case and map-fn cases run per constructor.
Iteration & iterators
tests/built-ins/TypedArray/prototype/entries.js, tests/built-ins/TypedArray/prototype/keys.js, tests/built-ins/TypedArray/prototype/values.js, tests/built-ins/TypedArray/prototype/symbol-iterator.js
Generalized iterator, spread, and protocol tests to run per numeric TypedArray constructor; added stepwise next() checks and preserved BigInt suites.
Indexing / search / predicate methods
tests/built-ins/TypedArray/prototype/at.js, .../includes.js, .../indexOf.js, .../lastIndexOf.js, .../find.js, .../findIndex.js, .../findLast.js, .../findLastIndex.js
Converted Int32Array-specific search/predicate tests into parameterized suites across numeric typed arrays; thisArg, TypeError, and edge-case behaviors tested per constructor; BigInt tests unchanged.
Iteration callbacks & aggregations
tests/built-ins/TypedArray/prototype/forEach.js, .../every.js, .../some.js, .../reduce.js, .../reduceRight.js
Rewrote callback and reducer tests to run across numeric typed arrays, checking visitation order, return values, thisArg forwarding, empty/single-element behaviors and TypeError on missing callbacks.
Transform & copy methods
tests/built-ins/TypedArray/prototype/map.js, .../filter.js, .../slice.js, .../copyWithin.js, .../set.js, .../with.js
Parameterized mapping, filtering, slicing, copyWithin, set, and with tests across numeric typed arrays; added instance/type assertions and generalized RangeError/overflow cases; BigInt suites preserved.
In-place / mutation / ordering
tests/built-ins/TypedArray/prototype/fill.js, .../reverse.js, .../sort.js, .../toReversed.js, .../toSorted.js
Moved in-place and ordering tests into per-constructor describe.each blocks; added NaN and signed-zero expectations for float kinds and ensured returned-instance and non-mutation checks for copy-producing APIs.
String/representation & misc
tests/built-ins/TypedArray/prototype/join.js, .../toString.js, .../toString-tag.js, .../keys.js, .../values.js, .../at.js
Consolidated various small Int32-specific tests into per-constructor suites; added Float16Array to toStringTag checks and a join-separator Symbol TypeError assertion.
Pascal runtime change
source/units/Goccia.Values.TypedArrayValue.pas
Adjusted TGocciaTypedArrayValue.TypedArraySort no-comparefn path for float kinds to distinguish -0 vs +0 via IEEE-754 bit inspection and enforce -0 < +0; added local variables to support bitwise checks.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Expand typed array coverage across core methods' clearly summarizes the main change: broadening test coverage for TypedArray methods.
Description check ✅ Passed The description covers the primary changes (expanded TypedArray test coverage, new parameterized test suites), though it omits explicit testing verification checkboxes from the template.
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 the spec compliance Mismatch against official JavaScript/TypeScript specification label 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.

🧹 Nitpick comments (5)
tests/built-ins/TypedArray/prototype/toString-tag.js (1)

38-55: Unify constructor sources to prevent test drift.

Line 46 adds Float16Array here, but the earlier constructors list (Line 2–14) is separate and still excludes it, so descriptor/getter-path assertions are not exercised for Float16Array. Use one shared constructor table for both sections.

♻️ Suggested refactor
 describe("TypedArray Symbol.toStringTag", () => {
-  const constructors = [
-    [Int8Array, "[object Int8Array]"],
-    [Uint8Array, "[object Uint8Array]"],
-    [Uint8ClampedArray, "[object Uint8ClampedArray]"],
-    [Int16Array, "[object Int16Array]"],
-    [Uint16Array, "[object Uint16Array]"],
-    [Int32Array, "[object Int32Array]"],
-    [Uint32Array, "[object Uint32Array]"],
-    [Float32Array, "[object Float32Array]"],
-    [Float64Array, "[object Float64Array]"],
-    [BigInt64Array, "[object BigInt64Array]"],
-    [BigUint64Array, "[object BigUint64Array]"],
-  ];
+  const constructors = [
+    [Int8Array, "Int8Array"],
+    [Uint8Array, "Uint8Array"],
+    [Uint8ClampedArray, "Uint8ClampedArray"],
+    [Int16Array, "Int16Array"],
+    [Uint16Array, "Uint16Array"],
+    [Int32Array, "Int32Array"],
+    [Uint32Array, "Uint32Array"],
+    [Float16Array, "Float16Array"],
+    [Float32Array, "Float32Array"],
+    [Float64Array, "Float64Array"],
+    [BigInt64Array, "BigInt64Array"],
+    [BigUint64Array, "BigUint64Array"],
+  ];
   constructors.forEach((pair) => {
     const Ctor = pair[0];
-    const tag = pair[1];
+    const shortTag = pair[1];
+    const tag = "[object " + shortTag + "]";
@@
-      const shortTag = tag.slice(8, -1);
       expect(desc.get.call(new Ctor(0))).toBe(shortTag);
@@
-  test.each([
-    [Int8Array, "Int8Array"],
-    [Uint8Array, "Uint8Array"],
-    [Uint8ClampedArray, "Uint8ClampedArray"],
-    [Int16Array, "Int16Array"],
-    [Uint16Array, "Uint16Array"],
-    [Int32Array, "Int32Array"],
-    [Uint32Array, "Uint32Array"],
-    [Float16Array, "Float16Array"],
-    [Float32Array, "Float32Array"],
-    [Float64Array, "Float64Array"],
-    [BigInt64Array, "BigInt64Array"],
-    [BigUint64Array, "BigUint64Array"],
-  ])("%s has correct @@toStringTag", (TA, expected) => {
+  test.each(constructors)("%s has correct @@toStringTag", (TA, expected) => {
     const ta = new TA(0);
     expect(Object.prototype.toString.call(ta)).toBe("[object " + expected + "]");
     expect(ta[Symbol.toStringTag]).toBe(expected);
   });
🤖 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 38 - 55,
The test added Float16Array to the test.each table but not to the earlier
constructors array, causing descriptor/getter-path checks to skip Float16Array;
consolidate by creating and exporting/using a single shared constructors
collection (e.g., rename the existing constructors array or create a shared
const like constructorsList) and reference that same identifier in both the
toStringTag test (the test.each([...]) and the earlier descriptor/getter-path
assertions) so Float16Array is included in both test sections.
tests/built-ins/TypedArray/prototype/symbol-iterator.js (1)

46-59: Optional: add BigInt iterator parity tests in this file.

A small test.each([BigInt64Array, BigUint64Array]) block for the same spread/iteration assertions would align this file with other iterator suites.

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

In `@tests/built-ins/TypedArray/prototype/symbol-iterator.js` around lines 46 -
59, Add parity tests for BigInt typed arrays by adding a new test.each block for
BigInt64Array and BigUint64Array that mirrors the existing checks: create a TA
instance with [1n, 2n, 3n], assert that [...ta] equals [1n,2n,3n], and assert
that a for-of loop over ta collects [1n,2n,3n]; reference the same test patterns
used in the existing describe.each for Int8Array etc., and use the constructors
BigInt64Array and BigUint64Array to locate where to add the block.
tests/built-ins/TypedArray/prototype/sort.js (1)

73-95: Optional: add a float-specific edge case for sort().

Consider one targeted case for Float16Array/Float32Array/Float64Array involving NaN (and optionally -0/+0) to guard numeric ordering edge semantics.

🤖 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 73 - 95, Add a
targeted test inside the existing describe.each block for Float16Array,
Float32Array, and Float64Array that verifies sort() handles NaN (and optionally
-0/+0) correctly: locate the describe.each([...]) block and add a new test
(e.g., "handles NaN and signed zero") that constructs a TA with values like
[NaN, 1, -0, 0, 2] (or similar), calls ta.sort(), and asserts the expected
post-sort ordering for that TA subclass (NaN should end up at the end and +0/-0
ordering as per spec) while using the same TA variable name and test harness
(test(...), expect(...)) so it integrates with the existing tests for
Float16Array/Float32Array/Float64Array.
tests/built-ins/TypedArray/prototype/toSorted.js (1)

32-36: Make the non-mutation test fully assertive.

Line 35 checks only the first slot, so partial mutations can slip through. Verify all elements remain unchanged after toSorted().

Suggested test tightening
     test("does not modify original", () => {
       const ta = new TA([3, 1, 2]);
       ta.toSorted();
       expect(ta[0]).toBe(3);
+      expect(ta[1]).toBe(1);
+      expect(ta[2]).toBe(2);
     });
Based on learnings: JavaScript tests should cover happy paths, edge cases, and error cases. Keep tests isolated and grouped by feature/filename.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/toSorted.js` around lines 32 - 36, The
non-mutation test for TA.prototype.toSorted only asserts ta[0] and can miss
other mutations; update the test that creates const ta = new TA([3, 1, 2]) and
calls ta.toSorted() to assert that all elements of ta remain unchanged (e.g.,
compare the entire contents of ta to [3,1,2] using a full equality check or by
converting TA to a plain array), referencing the variable ta and the method
toSorted to ensure the original TypedArray is not modified.
tests/built-ins/TypedArray/prototype/toReversed.js (1)

35-39: Strengthen immutability assertion beyond the first element.

Line 38 only validates index 0; a buggy implementation mutating later slots would still pass. Assert the full array state after toReversed().

Suggested test tightening
     test("does not modify original", () => {
       const ta = new TA([1, 2, 3]);
       ta.toReversed();
-      expect(ta[0]).toBe(1);
+      expect(ta[0]).toBe(1);
+      expect(ta[1]).toBe(2);
+      expect(ta[2]).toBe(3);
     });
Based on learnings: JavaScript tests should cover happy paths, edge cases, and error cases. Keep tests isolated and grouped by feature/filename.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/toReversed.js` around lines 35 - 39, The
test for TA.prototype.toReversed only checks ta[0], which can miss mutations to
other indices; update the "does not modify original" test that uses TA and
ta.toReversed() to assert the entire typed array remains unchanged (same length
and same sequence of elements) after calling toReversed() rather than only
checking index 0, so any in-place modifications to later slots will fail the
test.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/built-ins/TypedArray/prototype/sort.js`:
- Around line 73-95: Add a targeted test inside the existing describe.each block
for Float16Array, Float32Array, and Float64Array that verifies sort() handles
NaN (and optionally -0/+0) correctly: locate the describe.each([...]) block and
add a new test (e.g., "handles NaN and signed zero") that constructs a TA with
values like [NaN, 1, -0, 0, 2] (or similar), calls ta.sort(), and asserts the
expected post-sort ordering for that TA subclass (NaN should end up at the end
and +0/-0 ordering as per spec) while using the same TA variable name and test
harness (test(...), expect(...)) so it integrates with the existing tests for
Float16Array/Float32Array/Float64Array.

In `@tests/built-ins/TypedArray/prototype/symbol-iterator.js`:
- Around line 46-59: Add parity tests for BigInt typed arrays by adding a new
test.each block for BigInt64Array and BigUint64Array that mirrors the existing
checks: create a TA instance with [1n, 2n, 3n], assert that [...ta] equals
[1n,2n,3n], and assert that a for-of loop over ta collects [1n,2n,3n]; reference
the same test patterns used in the existing describe.each for Int8Array etc.,
and use the constructors BigInt64Array and BigUint64Array to locate where to add
the block.

In `@tests/built-ins/TypedArray/prototype/toReversed.js`:
- Around line 35-39: The test for TA.prototype.toReversed only checks ta[0],
which can miss mutations to other indices; update the "does not modify original"
test that uses TA and ta.toReversed() to assert the entire typed array remains
unchanged (same length and same sequence of elements) after calling toReversed()
rather than only checking index 0, so any in-place modifications to later slots
will fail the test.

In `@tests/built-ins/TypedArray/prototype/toSorted.js`:
- Around line 32-36: The non-mutation test for TA.prototype.toSorted only
asserts ta[0] and can miss other mutations; update the test that creates const
ta = new TA([3, 1, 2]) and calls ta.toSorted() to assert that all elements of ta
remain unchanged (e.g., compare the entire contents of ta to [3,1,2] using a
full equality check or by converting TA to a plain array), referencing the
variable ta and the method toSorted to ensure the original TypedArray is not
modified.

In `@tests/built-ins/TypedArray/prototype/toString-tag.js`:
- Around line 38-55: The test added Float16Array to the test.each table but not
to the earlier constructors array, causing descriptor/getter-path checks to skip
Float16Array; consolidate by creating and exporting/using a single shared
constructors collection (e.g., rename the existing constructors array or create
a shared const like constructorsList) and reference that same identifier in both
the toStringTag test (the test.each([...]) and the earlier
descriptor/getter-path assertions) so Float16Array is included in both test
sections.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fe7eb59f-c586-4774-8230-c192861e056f

📥 Commits

Reviewing files that changed from the base of the PR and between cd6282b and 1d03f43.

📒 Files selected for processing (34)
  • 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/keys.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/symbol-iterator.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/toString.js
  • tests/built-ins/TypedArray/prototype/values.js
  • tests/built-ins/TypedArray/prototype/with.js

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 20, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 7476 7476
Tests Passed 7435 ✅ 7476 ✅
Tests Skipped 41 0
Tests Workers 4 4
Tests Test Duration 1.41s 1.10s
Tests Lex (cumulative) 187.3ms 79.6ms
Tests Parse (cumulative) 258.1ms 180.3ms
Tests Compile (cumulative) 116.9ms
Tests Execute (cumulative) 1.62s 1.32s
Tests Engine Total (cumulative) 2.06s 1.69s
Tests Lex (avg/worker) 46.8ms 19.9ms
Tests Parse (avg/worker) 64.5ms 45.1ms
Tests Compile (avg/worker) 29.2ms
Tests Execute (avg/worker) 404.1ms 328.8ms
Tests Engine Total (avg/worker) 515.4ms 423.0ms
Benchmarks Total 386 386
Benchmarks Workers 4 4
Benchmarks Duration 3.27min 2.79min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 20, 2026

Benchmark Results

386 benchmarks

Interpreted: 🟢 216 improved · 🔴 66 regressed · 104 unchanged · avg +2.8%
Bytecode: 🟢 106 improved · 🔴 47 regressed · 233 unchanged · avg +0.6%

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

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.

- Remove overlapping TypedArray coverage across built-in tests
- Keep representative cases for edge behavior and callback errors
@coderabbitai coderabbitai Bot added the internal Refactoring, CI, tooling, cleanup label 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.

🧹 Nitpick comments (2)
tests/built-ins/TypedArray/prototype/join.js (1)

14-29: Consider adding one error-path join case (single shared test).

A small follow-up like expect(() => ta.join(Symbol())).toThrow(TypeError) would complete happy/edge/error coverage without much extra test weight.

Based on learnings: JavaScript tests should cover happy paths, edge cases, and error cases. Keep tests isolated and grouped by feature/filename.

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

In `@tests/built-ins/TypedArray/prototype/join.js` around lines 14 - 29, Add a
single shared error-path test to the existing describe.each block that asserts
using a Symbol as the separator throws a TypeError: create a new test (e.g.,
"throws on non-string separator") inside the same describe.each([...]) where TA
is available, construct a small TA like new TA([1,2]) and call expect(() =>
ta.join(Symbol())).toThrow(TypeError), referencing the join method and the TA
constructor so the failure case is covered for all typed arrays.
tests/built-ins/TypedArray/prototype/filter.js (1)

27-27: Consider centralizing the numeric constructor list into a shared test helper/constant.

The inline constructor matrix is likely to repeat across TypedArray prototype suites; extracting it would reduce drift when adding/removing supported constructors.

🤖 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` at line 27, Extract the
inline constructor array used in describe.each([...]) into a single exported
constant (e.g., NUMERIC_TYPED_ARRAYS or TYPED_ARRAY_CONSTRUCTORS) in a shared
test helper module and replace the inline array in this file's describe.each
call with that imported constant; update other TypedArray prototype tests to
import and use the same constant so all suites (which currently use the TA
variable in their describe.each) share one canonical list and avoid duplication.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/built-ins/TypedArray/prototype/filter.js`:
- Line 27: Extract the inline constructor array used in describe.each([...])
into a single exported constant (e.g., NUMERIC_TYPED_ARRAYS or
TYPED_ARRAY_CONSTRUCTORS) in a shared test helper module and replace the inline
array in this file's describe.each call with that imported constant; update
other TypedArray prototype tests to import and use the same constant so all
suites (which currently use the TA variable in their describe.each) share one
canonical list and avoid duplication.

In `@tests/built-ins/TypedArray/prototype/join.js`:
- Around line 14-29: Add a single shared error-path test to the existing
describe.each block that asserts using a Symbol as the separator throws a
TypeError: create a new test (e.g., "throws on non-string separator") inside the
same describe.each([...]) where TA is available, construct a small TA like new
TA([1,2]) and call expect(() => ta.join(Symbol())).toThrow(TypeError),
referencing the join method and the TA constructor so the failure case is
covered for all typed arrays.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a931961d-aa37-4e68-be33-b8f608b220be

📥 Commits

Reviewing files that changed from the base of the PR and between 1d03f43 and add0749.

📒 Files selected for processing (33)
  • 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/keys.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/symbol-iterator.js
  • tests/built-ins/TypedArray/prototype/toReversed.js
  • tests/built-ins/TypedArray/prototype/toSorted.js
  • tests/built-ins/TypedArray/prototype/toString.js
  • tests/built-ins/TypedArray/prototype/values.js
  • tests/built-ins/TypedArray/prototype/with.js
✅ Files skipped from review due to trivial changes (4)
  • tests/built-ins/TypedArray/prototype/find.js
  • tests/built-ins/TypedArray/prototype/reduceRight.js
  • tests/built-ins/TypedArray/prototype/reverse.js
  • tests/built-ins/TypedArray/from.js
🚧 Files skipped from review as they are similar to previous changes (26)
  • tests/built-ins/TypedArray/prototype/toString.js
  • tests/built-ins/TypedArray/prototype/indexOf.js
  • tests/built-ins/TypedArray/prototype/keys.js
  • tests/built-ins/TypedArray/prototype/subarray.js
  • tests/built-ins/TypedArray/prototype/with.js
  • tests/built-ins/TypedArray/prototype/set.js
  • tests/built-ins/TypedArray/prototype/copyWithin.js
  • tests/built-ins/TypedArray/prototype/findIndex.js
  • tests/built-ins/TypedArray/prototype/map.js
  • tests/built-ins/TypedArray/prototype/toReversed.js
  • tests/built-ins/TypedArray/prototype/at.js
  • tests/built-ins/TypedArray/prototype/findLastIndex.js
  • tests/built-ins/TypedArray/prototype/entries.js
  • tests/built-ins/TypedArray/prototype/every.js
  • tests/built-ins/TypedArray/prototype/reduce.js
  • tests/built-ins/TypedArray/prototype/some.js
  • tests/built-ins/TypedArray/prototype/findLast.js
  • tests/built-ins/TypedArray/prototype/forEach.js
  • tests/built-ins/TypedArray/prototype/sort.js
  • tests/built-ins/TypedArray/prototype/fill.js
  • tests/built-ins/TypedArray/prototype/values.js
  • tests/built-ins/TypedArray/prototype/slice.js
  • tests/built-ins/TypedArray/prototype/symbol-iterator.js
  • tests/built-ins/TypedArray/prototype/lastIndexOf.js
  • tests/built-ins/TypedArray/of.js
  • tests/built-ins/TypedArray/prototype/toSorted.js

Rewrite all TypedArray prototype tests to exercise every behavior across
all 10 numeric typed array types via describe.each, rather than only
testing Int32Array. This caught a real bug: TypedArray.prototype.sort
treated -0 and +0 as equal due to Pascal's comparison operators not
distinguishing them. Fix the sort comparison to check sign bits when
both values are zero in float typed arrays, ensuring -0 sorts before +0
per spec.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai coderabbitai Bot added the bug Something isn't working label 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.

🧹 Nitpick comments (3)
tests/built-ins/TypedArray/prototype/find.js (1)

3-23: Optional: add an early-exit assertion for callback invocation count.

This would tighten find semantics coverage by ensuring iteration stops at the first match.

Suggested test addition
   describe.each([Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float16Array, Float32Array, Float64Array])("%s", (TA) => {
+    test("stops at first match", () => {
+      const ta = new TA([1, 2, 3, 4, 5]);
+      let calls = 0;
+      const result = ta.find((x) => {
+        calls++;
+        return x === 3;
+      });
+
+      expect(result).toBe(3);
+      expect(calls).toBe(3);
+    });
+
     test("returns matching element", () => {
       const ta = new TA([1, 2, 3, 4]);
       expect(ta.find(x => x > 2)).toBe(3);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/find.js` around lines 3 - 23, Add an
assertion ensuring the callback is invoked only until the first match to
validate early-exit behavior of TypedArray.prototype.find: in the "passes
thisArg to callback" test (using TA and ta.find), wrap or replace the callback
with a spy/counter (e.g., increment a local counter inside obj.fn or use a stub)
and assert after the call that the counter equals 1 (or the expected number) so
the iteration stops once the matching element is found; keep the existing
thisArg assertion intact.
tests/built-ins/TypedArray/prototype/keys.js (1)

15-25: Consider adding an explicit error-path assertion for receiver brand checks.

iterator protocol coverage is good; adding one non-TypedArray receiver case would complete happy/edge/error coverage in this suite.

Proposed test addition
   describe.each([Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float16Array, Float32Array, Float64Array])("%s", (TA) => {
@@
     test("iterator protocol", () => {
       const ta = new TA([1, 2]);
       const iter = ta.keys();
@@
       expect(iter.next().done).toBe(true);
     });
+
+    test("throws on non-TypedArray receiver", () => {
+      expect(() => TA.prototype.keys.call({})).toThrow(TypeError);
+    });
   });

Based on learnings: JavaScript tests should cover happy paths, edge cases, and error cases, while staying isolated by feature/file.

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

In `@tests/built-ins/TypedArray/prototype/keys.js` around lines 15 - 25, Add a
negative test asserting that TypedArray.prototype.keys (the iterator produced by
TA.prototype.keys / ta.keys()) throws when called with a non-TypedArray
receiver: call the keys function with a plain object or an Array instance as the
receiver (e.g., Function.prototype.call or .call on TA.prototype.keys) and
assert it throws a TypeError; place this alongside the existing "iterator
protocol" test to cover receiver brand checks for keys().
tests/built-ins/TypedArray/prototype/toReversed.js (1)

2-35: Add receiver validation test to cover error case.

The suite validates success paths but lacks an error-case assertion for invalid receivers. The pattern exists in indexOf.js (test("throws on non-TypedArray receiver", ...)) and should be included here to match spec requirements and the learning guideline to cover edge cases.

✅ Suggested test addition
   describe.each([Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float16Array, Float32Array, Float64Array])("%s", (TA) => {
+    test("throws on invalid receiver", () => {
+      expect(() => TA.prototype.toReversed.call([])).toThrow(TypeError);
+      expect(() => TA.prototype.toReversed.call({ 0: 1, length: 1 })).toThrow(TypeError);
+    });
+
     test("returns reversed copy", () => {
       const ta = new TA([1, 2, 3]);
       const reversed = ta.toReversed();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/built-ins/TypedArray/prototype/toReversed.js` around lines 2 - 35, Add
a negative test that validates receiver checks for
TypedArray.prototype.toReversed: create a test named "throws on non-TypedArray
receiver" (matching the pattern in indexOf.js) and assert that calling
TypedArray.prototype.toReversed with an invalid receiver (e.g., call with {} or
[] via .call) throws a TypeError; place this test inside the same describe.each
block so it runs for each TA type and references toReversed and the TA
constructor to locate where to add it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/built-ins/TypedArray/prototype/find.js`:
- Around line 3-23: Add an assertion ensuring the callback is invoked only until
the first match to validate early-exit behavior of TypedArray.prototype.find: in
the "passes thisArg to callback" test (using TA and ta.find), wrap or replace
the callback with a spy/counter (e.g., increment a local counter inside obj.fn
or use a stub) and assert after the call that the counter equals 1 (or the
expected number) so the iteration stops once the matching element is found; keep
the existing thisArg assertion intact.

In `@tests/built-ins/TypedArray/prototype/keys.js`:
- Around line 15-25: Add a negative test asserting that
TypedArray.prototype.keys (the iterator produced by TA.prototype.keys /
ta.keys()) throws when called with a non-TypedArray receiver: call the keys
function with a plain object or an Array instance as the receiver (e.g.,
Function.prototype.call or .call on TA.prototype.keys) and assert it throws a
TypeError; place this alongside the existing "iterator protocol" test to cover
receiver brand checks for keys().

In `@tests/built-ins/TypedArray/prototype/toReversed.js`:
- Around line 2-35: Add a negative test that validates receiver checks for
TypedArray.prototype.toReversed: create a test named "throws on non-TypedArray
receiver" (matching the pattern in indexOf.js) and assert that calling
TypedArray.prototype.toReversed with an invalid receiver (e.g., call with {} or
[] via .call) throws a TypeError; place this test inside the same describe.each
block so it runs for each TA type and references toReversed and the TA
constructor to locate where to add it.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aa377fd3-734b-4f77-9a2a-6452f6708196

📥 Commits

Reviewing files that changed from the base of the PR and between add0749 and f88825a.

📒 Files selected for processing (34)
  • source/units/Goccia.Values.TypedArrayValue.pas
  • 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/keys.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/symbol-iterator.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
✅ Files skipped from review due to trivial changes (4)
  • tests/built-ins/TypedArray/prototype/at.js
  • tests/built-ins/TypedArray/prototype/some.js
  • tests/built-ins/TypedArray/of.js
  • tests/built-ins/TypedArray/prototype/findLastIndex.js
🚧 Files skipped from review as they are similar to previous changes (25)
  • tests/built-ins/TypedArray/from.js
  • tests/built-ins/TypedArray/prototype/join.js
  • tests/built-ins/TypedArray/prototype/copyWithin.js
  • tests/built-ins/TypedArray/prototype/findIndex.js
  • tests/built-ins/TypedArray/prototype/forEach.js
  • tests/built-ins/TypedArray/prototype/lastIndexOf.js
  • tests/built-ins/TypedArray/prototype/toString-tag.js
  • tests/built-ins/TypedArray/prototype/set.js
  • tests/built-ins/TypedArray/prototype/with.js
  • tests/built-ins/TypedArray/prototype/symbol-iterator.js
  • tests/built-ins/TypedArray/prototype/every.js
  • tests/built-ins/TypedArray/prototype/reduce.js
  • tests/built-ins/TypedArray/prototype/toSorted.js
  • tests/built-ins/TypedArray/prototype/findLast.js
  • tests/built-ins/TypedArray/prototype/fill.js
  • tests/built-ins/TypedArray/prototype/indexOf.js
  • tests/built-ins/TypedArray/prototype/entries.js
  • tests/built-ins/TypedArray/prototype/includes.js
  • tests/built-ins/TypedArray/prototype/map.js
  • tests/built-ins/TypedArray/prototype/reverse.js
  • tests/built-ins/TypedArray/prototype/reduceRight.js
  • tests/built-ins/TypedArray/prototype/sort.js
  • tests/built-ins/TypedArray/prototype/filter.js
  • tests/built-ins/TypedArray/prototype/subarray.js
  • tests/built-ins/TypedArray/prototype/values.js

- find.js: assert iteration stops after first match
- keys.js: assert TypeError on non-TypedArray receiver
- toReversed.js: assert TypeError on non-TypedArray receiver

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

Labels

bug Something isn't working internal Refactoring, CI, tooling, cleanup spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant