Skip to content

Fix ModuleResolver alias segment boundary matching#149

Merged
frostney merged 1 commit into
mainfrom
fix/issue-113-module-alias-boundary
Mar 31, 2026
Merged

Fix ModuleResolver alias segment boundary matching#149
frostney merged 1 commit into
mainfrom
fix/issue-113-module-alias-boundary

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Mar 31, 2026

Summary

  • centralize alias matching so HasAlias and ApplyAliases both require an exact match or a / segment boundary
  • add native regression tests for exact matches, child-path matches, rejected partial-segment matches, and longest-prefix behavior
  • document the segment-boundary rule in the module resolution docs

Closes #113

Verification

  • ./build.pas tests
  • for t in build/Goccia.*.Test; do "$t"; done
  • ./build.pas testrunner
  • ./build/TestRunner tests --no-progress --exit-on-first-failure

Summary by CodeRabbit

Release Notes

  • Documentation

    • Clarified module alias matching behavior: aliases now strictly match exact specifiers or subsequent paths with proper segment boundaries, preventing unintended partial matches.
  • Tests

    • Added comprehensive test coverage for alias matching and resolution, validating segment boundary conditions and longest-prefix matching scenarios.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 31, 2026

📝 Walkthrough

Walkthrough

Enforces segment-boundary validation in module alias prefix matching by introducing a shared helper function that ensures aliases match only exact specifiers or paths delimited by /. Updates documentation, implementation, and adds comprehensive tests to verify the stricter matching behavior.

Changes

Cohort / File(s) Summary
Documentation
docs/design-decisions.md, docs/embedding.md
Clarified module alias resolution rules to specify exact-or-/ segment boundary matching instead of plain prefix matching.
Implementation
units/ModuleResolver.pas
Extracted alias boundary-matching logic into helper AliasMatchesModulePath, added ALIAS_SEGMENT_DELIMITER constant, and updated HasAlias and ApplyAliases to enforce segment boundaries.
Tests
units/Goccia.ModuleResolver.Test.pas
Added new test unit with five test cases covering exact matches, segment-boundary matches, partial-segment rejection, and longest-boundary preference in alias resolution.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • PR #17: Touches module resolver alias-matching logic in TGocciaModuleResolver.ApplyAliases and HasAlias; this PR tightens those same methods to enforce segment boundaries.

Poem

🐰 With forward slashes, boundaries are clear,
No partial matches shall interfere!
@lib knows its place, / marks the way,
Aliases dance in the correct ballet. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: implementing segment boundary matching for module resolver aliases.
Linked Issues check ✅ Passed The PR fully implements the requirements from issue #113: centralizes alias matching logic, enforces segment boundaries in both HasAlias and ApplyAliases, adds comprehensive regression tests, and documents the behavior.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #113: alias matching logic updates, segment boundary documentation, and related regression tests only.
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.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-113-module-alias-boundary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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.

🧹 Nitpick comments (1)
units/Goccia.ModuleResolver.Test.pas (1)

37-44: Add tests for aliases that end with / (e.g., @/, @/components/).

Current cases won’t catch regressions for the alias format used in embedding docs, where trailing / is common.

🧪 Suggested additional test cases
 procedure TModuleResolverTests.SetupTests;
 begin
   Test('HasAlias matches exact alias', TestHasAliasMatchesExactAlias);
   Test('HasAlias matches child path on segment boundary', TestHasAliasMatchesSegmentChild);
   Test('HasAlias rejects partial segment match', TestHasAliasRejectsPartialSegmentMatch);
   Test('ApplyAliases leaves partial segment unchanged', TestApplyAliasesLeavesPartialSegmentUnchanged);
   Test('ApplyAliases uses longest boundary-matched alias', TestApplyAliasesUsesLongestBoundaryMatchedAlias);
+  Test('HasAlias matches child path for trailing-slash alias', TestHasAliasMatchesTrailingSlashAliasChild);
+  Test('ApplyAliases rewrites trailing-slash alias child path', TestApplyAliasesRewritesTrailingSlashAliasChildPath);
 end;
procedure TModuleResolverTests.TestHasAliasMatchesTrailingSlashAliasChild;
var
  Resolver: TTestModuleResolver;
begin
  Resolver := CreateResolver;
  try
    Resolver.AddAlias('@/', 'src/');
    Expect<Boolean>(Resolver.HasAlias('@/utils/math')).ToBe(True);
  finally
    Resolver.Free;
  end;
end;

procedure TModuleResolverTests.TestApplyAliasesRewritesTrailingSlashAliasChildPath;
var
  Resolver: TTestModuleResolver;
begin
  Resolver := CreateResolver;
  try
    Resolver.AddAlias('@/', 'src/');
    Expect<string>(Resolver.ExposedApplyAliases('@/utils/math')).ToBe(
      Resolver.BaseDirectory + 'src/utils/math');
  finally
    Resolver.Free;
  end;
end;

Also applies to: 107-121

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

In `@units/Goccia.ModuleResolver.Test.pas` around lines 37 - 44, Add tests
covering aliases that end with '/' by implementing two new test methods:
TestHasAliasMatchesTrailingSlashAliasChild and
TestApplyAliasesRewritesTrailingSlashAliasChildPath (create them following the
pattern of existing tests that use CreateResolver, AddAlias('@/','src/'), call
HasAlias('@/utils/math') and ExposedApplyAliases('@/utils/math') respectively).
Register these new methods in TModuleResolverTests.SetupTests alongside the
other Test(...) registrations so they run with the suite; also add the actual
test implementations near the other test methods (the block around the existing
ApplyAliases/HasAlias tests).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@units/Goccia.ModuleResolver.Test.pas`:
- Around line 37-44: Add tests covering aliases that end with '/' by
implementing two new test methods: TestHasAliasMatchesTrailingSlashAliasChild
and TestApplyAliasesRewritesTrailingSlashAliasChildPath (create them following
the pattern of existing tests that use CreateResolver, AddAlias('@/','src/'),
call HasAlias('@/utils/math') and ExposedApplyAliases('@/utils/math')
respectively). Register these new methods in TModuleResolverTests.SetupTests
alongside the other Test(...) registrations so they run with the suite; also add
the actual test implementations near the other test methods (the block around
the existing ApplyAliases/HasAlias tests).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5ffb1bb0-a715-4dc2-ac65-2ce7466070af

📥 Commits

Reviewing files that changed from the base of the PR and between 5c739c0 and 44173d6.

📒 Files selected for processing (4)
  • docs/design-decisions.md
  • docs/embedding.md
  • units/Goccia.ModuleResolver.Test.pas
  • units/ModuleResolver.pas

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results

263 benchmarks

Interpreted: 🟢 179 improved · 🔴 21 regressed · 63 unchanged · avg +5.0%
Bytecode: 🟢 36 improved · 🔴 154 regressed · 73 unchanged · avg -2.7%

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

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

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 3502 3502
Tests Passed 3461 ✅ 3502 ✅
Tests Skipped 41 0
Tests Execution 156.9ms 155.8ms
Tests Engine 311.1ms 572.2ms
Benchmarks Total 263 263
Benchmarks Duration 6.87min 5.95min

Measured on ubuntu-latest x64.

@frostney frostney merged commit 15250e1 into main Mar 31, 2026
9 checks passed
@frostney frostney deleted the fix/issue-113-module-alias-boundary branch March 31, 2026 21:26
@frostney frostney added the bug Something isn't working label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ModuleResolver: enforce segment boundary for alias prefix matching in HasAlias/ApplyAliases

1 participant