Skip to content

Add support for class static blocks#264

Merged
frostney merged 3 commits into
mainfrom
t3code/class-static-blocks
Apr 11, 2026
Merged

Add support for class static blocks#264
frostney merged 3 commits into
mainfrom
t3code/class-static-blocks

Conversation

@frostney
Copy link
Copy Markdown
Owner

Summary

  • Add parser, evaluator, compiler, and VM support for static { ... } class blocks.
  • Execute static blocks in source order with this bound to the class constructor, including support for inheritance and class expressions.
  • Extend bytecode with a dedicated OP_CLASS_EXEC_STATIC_BLOCK opcode.
  • Add end-to-end coverage for static block behavior and update the language restrictions docs.

Testing

  • Not run
  • Added tests/language/classes/static-blocks.js covering execution order, this binding, static fields/methods, private static fields, inheritance, and class expressions.
  • Updated docs/language-restrictions.md to document static blocks as supported syntax.

- Parse, compile, and execute `static { ... }` class blocks
- Add runtime coverage for class initialization order and `this` binding
- Document static blocks as a supported language feature
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 11, 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: a386cd2b-5d24-424f-a61c-8f52192c68da

📥 Commits

Reviewing files that changed from the base of the PR and between e86340a and 67cf597.

📒 Files selected for processing (2)
  • units/Goccia.Error.Suggestions.pas
  • units/Goccia.Parser.pas
✅ Files skipped from review due to trivial changes (1)
  • units/Goccia.Error.Suggestions.pas
🚧 Files skipped from review as they are similar to previous changes (1)
  • units/Goccia.Parser.pas

📝 Walkthrough

Walkthrough

Adds ES2022 class static block support: parser recognizes static { ... }, AST and bytecode carry static-block nodes/opcode, compiler emits closures + OP_CLASS_EXEC_STATIC_BLOCK, VM/evaluator invoke blocks with class as this; docs and tests added.

Changes

Cohort / File(s) Summary
Documentation & Tests
docs/language-restrictions.md, tests/language/classes/static-blocks.js
Documented static block support; added comprehensive tests for execution order, this binding, field/private access, closures, control flow, inheritance, class expressions, and independence across classes.
AST
units/Goccia.AST.Statements.pas
Added cekStaticBlock enum value and StaticBlockBody: TGocciaBlockStatement to class element record; destructor frees static block bodies.
Parser
units/Goccia.Parser.pas
ParseClassBody recognizes static { ... }, emits cekStaticBlock elements, enforces “no decorators” for static blocks, and records static fields as field elements when IsStatic.
Compiler
units/Goccia.Compiler.Statements.pas
Added CompileStaticBlock to produce a closure, emit OP_CLOSURE and register OP_CLASS_EXEC_STATIC_BLOCK; integrated static-block and static-field emission into a single source-order pass; added element descriptor for blocks.
Bytecode & Op Names
units/Goccia.Bytecode.pas, units/Goccia.Bytecode.OpCodeNames.pas
Introduced opcode OP_CLASS_EXEC_STATIC_BLOCK = 71 and its name mapping.
Evaluator & VM
units/Goccia.Evaluator.pas, units/Goccia.VM.pas
Evaluator: executes static block statements in a class-init scope with this bound to the class and evaluates static elements in source order. VM: handler for OP_CLASS_EXEC_STATIC_BLOCK invoking the closure with the class as this.
Errors / Suggestions
units/Goccia.Error.Suggestions.pas
Added SSuggestStaticBlockNoDecorators message for decorated static-block syntax errors.

Sequence Diagram(s)

sequenceDiagram
    participant Parser
    participant AST
    participant Compiler
    participant Bytecode
    participant VM
    participant Evaluator

    Parser->>AST: Parse class body -> emit cekStaticBlock element (BlockBody)
    AST->>Compiler: Provide class elements in source order
    Compiler->>Bytecode: CompileStaticBlock -> emit OP_CLOSURE + OP_CLASS_EXEC_STATIC_BLOCK
    Bytecode->>VM: Run class-definition bytecode
    VM->>Evaluator: OP_CLASS_EXEC_STATIC_BLOCK -> invoke closure with this=class
    Evaluator->>Evaluator: ExecuteStaticBlock statements in init scope (this bound)
    Evaluator-->>VM: Return/complete
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • Enforce private static brand checks #168: Modifies class-static semantics across compiler/evaluator/VM and introduces related opcode/compile-path changes.
  • Add decorators #35: Earlier changes to class-element AST and decorator handling that intersect with static-block decorator validation and element model.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the summary and includes added tests; however, it states 'Not run' under Testing and does not check the required testing checkboxes from the template. Complete the Testing section by checking appropriate boxes (at minimum 'Verified no regressions' or clarify test status) and confirm documentation was updated.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add support for class static blocks' directly and clearly summarizes the main change across all modified files—adding parser, compiler, evaluator, and VM support for ES2022 class static blocks.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the new feature New feature or request label Apr 11, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
units/Goccia.Compiler.Statements.pas (1)

2111-2142: ⚠️ Potential issue | 🟠 Major

Preserve source-order interleaving for static fields and static blocks.

These two passes still emit all static field initializers first and only then execute cekStaticBlock elements. That breaks the advertised source-order semantics for cases like class C { static { this.x = 1 } static y = this.x }, where y should see the block’s side effect. The static initializer path needs to be driven from ClassDef.FElements in a single ordered pass instead of mixing map iteration for fields with a later block-only pass.

Based on PR objectives, static blocks are expected to execute in source order.

Also applies to: 2279-2310

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

In `@units/Goccia.Compiler.Statements.pas` around lines 2111 - 2142, The current
code emits all static field initializers (ClassDef.StaticProperties /
ClassDef.PrivateStaticProperties and CompileComputedElements) and only afterward
emits static blocks (CompileStaticBlock), breaking source-order semantics;
change the logic to iterate ClassDef.FElements once in order and for each
element switch on its Kind: when it's a static field/public property, allocate
register, CompileExpression for its Value, add constant name (use same '#'
prefix for private), emit the OP_SET_PROP_CONST (and
OP_CLASS_DECLARE_PRIVATE_STATIC_CONST for private), free the register; when it's
a computed element call CompileComputedElements for that single element or
inline its handling; when it's cekStaticBlock call CompileStaticBlock
immediately; remove the separate map-based static-properties loops and the later
static-block-only pass so initializers and blocks are emitted in source order
(references: ClassDef.FElements, ClassDef.StaticProperties,
ClassDef.PrivateStaticProperties, CompileComputedElements, CompileStaticBlock,
OP_SET_PROP_CONST, OP_CLASS_DECLARE_PRIVATE_STATIC_CONST).
🧹 Nitpick comments (3)
units/Goccia.Evaluator.pas (1)

1744-1744: Use current spec edition year in the annotation.

Line 1744 uses ES2022; this file otherwise follows current-edition ESYYYY tags.

As per coding guidelines "When implementing ECMAScript-specified behavior, annotate each function or method with a comment referencing the relevant spec section using the format // ESYYYY §X.Y.Z ... where YYYY is the current edition year."

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

In `@units/Goccia.Evaluator.pas` at line 1744, Replace the hard-coded "ES2022" in
the comment annotating "ClassStaticBlockDefinition: execute static block body"
with the current ECMAScript edition tag used elsewhere in the file (i.e., change
ES2022 to the same ESYYYY year used by the other ESYYYY annotations) so the
comment matches the repository's current-spec-year convention.
tests/language/classes/static-blocks.js (2)

95-108: Cover super inside the inheritance case too.

This currently proves base-before-derived execution order, but not the inheritance-specific lookup semantics that usually break first. Adding one super read inside the child static block would make this case much more valuable.

Suggested test strengthening
   test("static blocks with inheritance", () => {
     const order = [];
     class Base {
+      static baseValue = 1;
       static {
         order.push("Base");
       }
     }
     class Child extends Base {
       static {
         order.push("Child");
+        this.inherited = super.baseValue;
       }
     }
     expect(order).toEqual(["Base", "Child"]);
+    expect(Child.inherited).toBe(1);
   });

As per coding guidelines, JavaScript end-to-end tests are the primary way of testing GocciaScript.

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

In `@tests/language/classes/static-blocks.js` around lines 95 - 108, The test
"static blocks with inheritance" currently only verifies execution order for
class Base and Child; modify the Child static block to perform a read of super
(e.g., access super.someProperty or call super in a harmless way) so the test
also exercises inheritance lookup semantics during static initialization—locate
the Child class static block in the test and add a benign super read to ensure
superclass property resolution is triggered while preserving the existing order
assertion on the order array.

239-246: This doesn't actually test the named class-expression binding.

this.value = 42 only shows the static block executed. If named class expressions are part of the feature surface, the assertion should prove that Named is visible inside the block and aliases the constructor.

Suggested assertion change
   test("named class expression with static block", () => {
     const MyClass = class Named {
       static {
-        this.value = 42;
+        this.value = Named === this;
       }
     };
-    expect(MyClass.value).toBe(42);
+    expect(MyClass.value).toBe(true);
   });

As per coding guidelines, JavaScript end-to-end tests are the primary way of testing GocciaScript.

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

In `@tests/language/classes/static-blocks.js` around lines 239 - 246, The test
currently only verifies the static block ran (this.value = 42) but does not
prove the named class-expression binding; update the test "named class
expression with static block" so the static block uses the inner name Named to
set a property showing it aliases the constructor (for example set a
flag/property on this when Named === this) and then assert that MyClass has that
property true; locate the class expression (const MyClass = class Named { static
{ ... } };) and modify the static block and final expect to assert the Named
binding equals the class constructor.
🤖 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.Evaluator.pas`:
- Around line 2008-2014: The static blocks are executed in a separate pass after
static-property processing, breaking source-order semantics; fix by executing
static blocks inline during the same single pass over AClassDef.FElements so
they interleave with static field definitions in source order. Locate the loop
that iterates AClassDef.FElements for static properties and, instead of
deferring cekStaticBlock handling to the later loop, call
ExecuteStaticBlock(AClassDef.FElements[I].StaticBlockBody, AContext, ClassValue)
immediately when AClassDef.FElements[I].Kind = cekStaticBlock; remove the
separate post-pass that currently runs static blocks.

In `@units/Goccia.Parser.pas`:
- Around line 2949-2964: The parser currently assigns MemberDecorators to a
static block element (when IsStatic and Check(gttLeftBrace) branch creates an
element with Kind := cekStaticBlock), but ECMAScript forbids decorators on class
static blocks; update that branch to detect if MemberDecorators is non-empty and
raise a TGocciaSyntaxError (with an appropriate message) instead of assigning
Decorators and creating the static block element; locate the block that sets
Elements[High(Elements)].Kind := cekStaticBlock and add the guard before copying
MemberDecorators/StaticBlockBody (or clear MemberDecorators) so static blocks
are rejected when decorators are present.

---

Outside diff comments:
In `@units/Goccia.Compiler.Statements.pas`:
- Around line 2111-2142: The current code emits all static field initializers
(ClassDef.StaticProperties / ClassDef.PrivateStaticProperties and
CompileComputedElements) and only afterward emits static blocks
(CompileStaticBlock), breaking source-order semantics; change the logic to
iterate ClassDef.FElements once in order and for each element switch on its
Kind: when it's a static field/public property, allocate register,
CompileExpression for its Value, add constant name (use same '#' prefix for
private), emit the OP_SET_PROP_CONST (and OP_CLASS_DECLARE_PRIVATE_STATIC_CONST
for private), free the register; when it's a computed element call
CompileComputedElements for that single element or inline its handling; when
it's cekStaticBlock call CompileStaticBlock immediately; remove the separate
map-based static-properties loops and the later static-block-only pass so
initializers and blocks are emitted in source order (references:
ClassDef.FElements, ClassDef.StaticProperties, ClassDef.PrivateStaticProperties,
CompileComputedElements, CompileStaticBlock, OP_SET_PROP_CONST,
OP_CLASS_DECLARE_PRIVATE_STATIC_CONST).

---

Nitpick comments:
In `@tests/language/classes/static-blocks.js`:
- Around line 95-108: The test "static blocks with inheritance" currently only
verifies execution order for class Base and Child; modify the Child static block
to perform a read of super (e.g., access super.someProperty or call super in a
harmless way) so the test also exercises inheritance lookup semantics during
static initialization—locate the Child class static block in the test and add a
benign super read to ensure superclass property resolution is triggered while
preserving the existing order assertion on the order array.
- Around line 239-246: The test currently only verifies the static block ran
(this.value = 42) but does not prove the named class-expression binding; update
the test "named class expression with static block" so the static block uses the
inner name Named to set a property showing it aliases the constructor (for
example set a flag/property on this when Named === this) and then assert that
MyClass has that property true; locate the class expression (const MyClass =
class Named { static { ... } };) and modify the static block and final expect to
assert the Named binding equals the class constructor.

In `@units/Goccia.Evaluator.pas`:
- Line 1744: Replace the hard-coded "ES2022" in the comment annotating
"ClassStaticBlockDefinition: execute static block body" with the current
ECMAScript edition tag used elsewhere in the file (i.e., change ES2022 to the
same ESYYYY year used by the other ESYYYY annotations) so the comment matches
the repository's current-spec-year convention.
🪄 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: 6e77bc36-bb16-4264-8a6b-475780bf6995

📥 Commits

Reviewing files that changed from the base of the PR and between 259e26b and 7e22ba8.

📒 Files selected for processing (9)
  • docs/language-restrictions.md
  • tests/language/classes/static-blocks.js
  • units/Goccia.AST.Statements.pas
  • units/Goccia.Bytecode.OpCodeNames.pas
  • units/Goccia.Bytecode.pas
  • units/Goccia.Compiler.Statements.pas
  • units/Goccia.Evaluator.pas
  • units/Goccia.Parser.pas
  • units/Goccia.VM.pas

Comment thread units/Goccia.Evaluator.pas Outdated
Comment thread units/Goccia.Parser.pas
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 11, 2026

Benchmark Results

324 benchmarks

Interpreted: 🟢 44 improved · 🔴 233 regressed · 47 unchanged · avg -3.1%
Bytecode: 🟢 42 improved · 🔴 201 regressed · 81 unchanged · avg -3.6%

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

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

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 4421 4421
Tests Passed 4380 ✅ 4421 ✅
Tests Skipped 41 0
Tests Test Duration 310.3ms 288.0ms
Tests Lex 83.5ms 60.3ms
Tests Parse 107.6ms 114.5ms
Tests Compile 67.9ms
Tests Execute 326.0ms 319.8ms
Tests Engine Total 517.1ms 562.5ms
Benchmarks Total 324 324
Benchmarks Duration 8.88min 7.99min

Measured on ubuntu-latest x64.

…ic blocks

Address CodeRabbit review feedback:
- Static fields and static blocks now execute in source order via a unified
  FElements pass (fixes interleaving semantics per ES2022 §15.7.14)
- Parser rejects decorators on static blocks with a SyntaxError
- Parser always adds static fields to FElements for source-order tracking
- HasDecorators check no longer falsely triggers for undecorated static fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai coderabbitai Bot added the documentation Improvements or additions to documentation label Apr 11, 2026
Use the suggestion-based error pattern (SSuggestStaticBlockNoDecorators)
so the error output includes the standard "Suggestion:" line.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@frostney frostney merged commit 340bb64 into main Apr 11, 2026
9 checks passed
@frostney frostney deleted the t3code/class-static-blocks branch April 11, 2026 08:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation new feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant