Skip to content

Support iterable inputs in Map.groupBy#317

Merged
frostney merged 3 commits into
mainfrom
t3code/fix-issue-310
Apr 16, 2026
Merged

Support iterable inputs in Map.groupBy#317
frostney merged 3 commits into
mainfrom
t3code/fix-issue-310

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 16, 2026

Summary

  • Expanded Map.groupBy to accept iterable sources, including arrays, sets, maps, strings, and custom iterables.
  • Preserved the array fast path while adding iterator-based handling for non-array inputs.
  • Added coverage for iterable sources, callback indices, empty iterables, and non-iterable TypeError cases.

Fixes #310

- Accept arrays, sets, maps, strings, and custom iterables
- Add coverage for non-iterables, empty iterables, and callback indices
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 16, 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: d8a61765-7d0f-4fec-9069-5da04b5fed13

📥 Commits

Reviewing files that changed from the base of the PR and between b826cb7 and 0b2b529.

📒 Files selected for processing (1)
  • units/Goccia.Builtins.GlobalMap.pas
✅ Files skipped from review due to trivial changes (1)
  • units/Goccia.Builtins.GlobalMap.pas

📝 Walkthrough

Walkthrough

Map.groupBy was extended to accept any iterable (arrays, Sets, Maps, strings, custom iterables) by adding iterator-protocol dispatch paths, refactoring grouping logic into a helper, and expanding tests to cover diverse inputs, edge cases, and non-iterable errors.

Changes

Cohort / File(s) Summary
Tests — Map.groupBy
tests/built-ins/Map/groupBy.js
Expanded tests to cover Set, Map, strings, and a custom iterable; verifies callback index for non-array iterables, asserts empty-iterable returns empty Map, and adds negative tests for non-iterable inputs (42, true, null).
Implementation — Map.groupBy
units/Goccia.Builtins.GlobalMap.pas
Widened source argument to accept general TGocciaValue. Added dispatch: fast array path, string iterator path, and object path that obtains/calls [Symbol.iterator] and wraps iterator results. Introduced AddToGroup helper, GC rooting for temporaries, and TypeError for non-iterables.

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant MapGroupBy as Map.groupBy
    participant Dispatch as DispatchLogic
    participant Iterator as Iterator
    participant Callback
    participant Result as ResultMap

    Caller->>MapGroupBy: call(source, callbackfn)
    MapGroupBy->>MapGroupBy: validate callbackfn
    MapGroupBy->>Dispatch: determine source type

    alt Array source
        Dispatch->>MapGroupBy: fast array path (indexing)
        MapGroupBy->>Callback: Invoke(value, index)
    else String source
        Dispatch->>Iterator: use string iterator
        Iterator->>Callback: Invoke(char, index)
    else Object with Symbol.iterator
        Dispatch->>Iterator: get & call Symbol.iterator
        Iterator->>Callback: Invoke(value, index)
    else Non-iterable
        Dispatch-->>MapGroupBy: throw TypeError
    end

    Callback-->>Dispatch: return groupKey
    Dispatch->>Result: find/create group for groupKey
    Result->>Result: append value to group
    MapGroupBy-->>Caller: return ResultMap
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Support iterable inputs in Map.groupBy' clearly summarizes the main change: expanding Map.groupBy to accept iterable inputs beyond arrays.
Description check ✅ Passed The description covers the key changes (iterable support, array fast path preservation, test coverage) and references the linked issue #310.
Linked Issues check ✅ Passed The PR implementation meets all acceptance criteria from #310: accepts arrays, Sets, Maps, and custom iterables via iterator protocol, preserves error handling for non-iterables, and maintains array test compatibility.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #310 objectives: test suite expansion for iterable support and Map.groupBy refactoring to handle iterables.
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.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/built-ins/Map/groupBy.js`:
- Around line 83-87: The test for Map.groupBy's non-iterable inputs is too loose
because it uses toThrow(); update the three assertions inside the "throws
TypeError for non-iterable" test to assert the specific error type (e.g.,
expect(() => Map.groupBy(42, () => "a")).toThrow(TypeError) or use toThrowError
with the expected message) so failures only pass when a TypeError is thrown by
Map.groupBy for non-iterable inputs; change the three expect lines that call
Map.groupBy with 42, true, and null accordingly.

In `@units/Goccia.Builtins.GlobalMap.pas`:
- Around line 77-93: The loop currently compares keys using
ToStringLiteral.Value which conflates distinct keys; replace that string-based
comparison with a proper Map-key equality check (e.g. call the key object's
equality method or compare the key reference/value directly) when iterating
ResultMap.Entries to find a matching key for GroupKey, and when a match is found
use the existing entry.Key (not the string) as the map key for the bucket;
update the code around ResultMap.Entries[K].Key, GroupKey and ResultMap.SetEntry
to use the equality check (e.g. ResultMap.Entries[K].Key.Equals(GroupKey) or an
appropriate reference/value comparison) and remove the ToStringLiteral.Value
comparisons so distinct keys (1 vs "1" or different objects) remain separate.
- Around line 109-123: The array fast-path in the global Map implementation
creates ResultMap (TGocciaMapValue) but does not protect it from GC before
calling AddToGroup on array elements; mirror the iterator branches by
rooting/protecting ResultMap (and any temp group arrays) prior to the while-loop
that calls AddToGroup and unrooting after the loop so partially-built maps
cannot be reclaimed if the callback triggers GC; locate the
ResultMap/TGocciaMapValue creation and the SourceArray/AddToGroup loop and apply
the same temp-rooting API used elsewhere in this unit to push ResultMap onto the
GC root stack before the loop and pop it afterwards.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 64f5dd03-6f69-4f43-a3a5-07e686bd4097

📥 Commits

Reviewing files that changed from the base of the PR and between 5daf610 and e4af5c6.

📒 Files selected for processing (2)
  • tests/built-ins/Map/groupBy.js
  • units/Goccia.Builtins.GlobalMap.pas

Comment thread tests/built-ins/Map/groupBy.js
Comment thread units/Goccia.Builtins.GlobalMap.pas Outdated
Comment thread units/Goccia.Builtins.GlobalMap.pas
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 16, 2026

Benchmark Results

364 benchmarks

Interpreted: 🟢 79 improved · 🔴 54 regressed · 231 unchanged · avg -0.6%
Bytecode: 🟢 300 improved · 🔴 18 regressed · 46 unchanged · avg +8.9%

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

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 16, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 5365 5365
Tests Passed 5324 ✅ 5365 ✅
Tests Skipped 41 0
Tests Test Duration 1.04s 892.6ms
Tests Lex 239.9ms 161.2ms
Tests Parse 275.2ms 244.1ms
Tests Compile 158.7ms
Tests Execute 1.07s 964.2ms
Tests Engine Total 1.59s 1.53s
Benchmarks Total 364 364
Benchmarks Duration 8.36min 8.09min

Measured on ubuntu-latest x64.

…ise error assertions

- Use Map.FindEntry (SameValueZero) instead of ToStringLiteral comparison
  for group key lookup, preserving key identity (e.g. 1 vs "1")
- Temp-root ResultMap on the array fast path to prevent GC reclamation
  when the callback triggers collection
- Assert TypeError specifically in non-iterable tests instead of bare toThrow()

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@units/Goccia.Builtins.GlobalMap.pas`:
- Around line 150-175: The call to IteratorMethod.Call (via
CallArgs/IteratorObj) can run user code before ResultMap is registered with the
GC, risking collection; move the temp-root registration for ResultMap
(TGarbageCollector.Instance.AddTempRoot(ResultMap)) to occur before invoking
TGocciaFunctionBase(IteratorMethod).Call, so ResultMap is rooted prior to any
user-callable execution, and keep the removal/cleanup in the existing
try/finally that currently surrounds GC roots; ensure you still create/free
CallArgs and preserve logic that inspects IteratorObj (TGocciaIteratorValue /
TGocciaObjectValue) and add Iterator to temp roots after determining it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2026c8a2-e0b7-45d8-9292-96626ea6cc4b

📥 Commits

Reviewing files that changed from the base of the PR and between e4af5c6 and b826cb7.

📒 Files selected for processing (2)
  • tests/built-ins/Map/groupBy.js
  • units/Goccia.Builtins.GlobalMap.pas
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/built-ins/Map/groupBy.js

Comment thread units/Goccia.Builtins.GlobalMap.pas Outdated
…path

The IteratorMethod.Call invocation executes user code, which may trigger
GC before ResultMap was rooted. Move AddTempRoot(ResultMap) to wrap the
entire object-iterator block, nesting the Iterator root inside it.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Widen Map.groupBy to accept any iterable (full iterator protocol)

1 participant