Skip to content

Consolidate engine semantics and test262 roadmap#494

Merged
frostney merged 8 commits intomainfrom
t3code/engine-runtime-analysis
May 2, 2026
Merged

Consolidate engine semantics and test262 roadmap#494
frostney merged 8 commits intomainfrom
t3code/engine-runtime-analysis

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented May 2, 2026

Summary

  • Extract shared arithmetic, bitwise, comparison, equality, and compound-assignment semantics into Goccia.Arithmetic for evaluator and VM fallback paths.
  • Add shared AST binding-pattern traversal for var-hoisting and compiler binding collection.
  • Replace the surgical test262 skip/filter model with an explicit compatibility roadmap and clustered reporting.
  • Add profiler-backed benchmark runner output so bytecode specialization work can be guided by opcode/function data.

Verification

  • ./build.pas clean testrunner loader
  • ./build.pas --prod testrunner loader
  • ./build/GocciaTestRunner tests --asi --unsafe-ffi --no-progress
  • ./build/GocciaTestRunner tests --asi --unsafe-ffi --mode=bytecode --no-progress
  • ./format.pas --check
  • git diff --check

Note: local pre-commit doc hooks scanned the untracked tmp/test262-suite checkout and failed on upstream test262 markdown files. tmp/ is not part of this commit.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 2, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Preview May 2, 2026 9:53am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 2, 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: e1bdb640-88d9-48c5-b325-a97a3126c899

📥 Commits

Reviewing files that changed from the base of the PR and between 4bd6c15 and d4c57dc.

📒 Files selected for processing (1)
  • scripts/test262_syntax_filter.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/test262_syntax_filter.py

📝 Walkthrough

Walkthrough

Consolidates arithmetic/bitwise/relational semantics into a new Goccia.Arithmetic unit and wires it across VM, evaluator, values, and compiler; centralizes destructuring binding-name collection; adds a Test262 compatibility roadmap, runner clustering, and CI comment rendering; integrates profiler support into the benchmark runner; plus docs, harness, BigInt parsing, and tests.

Changes

Arithmetic & Bitwise Consolidation

Layer / File(s) Summary
New Module & API
source/units/Goccia.Arithmetic.pas
New unit exporting arithmetic, bitwise, compound-assignment dispatch, strict/same-value equality, and relational comparisons over TGocciaValue.
Remove legacy evaluator modules
source/units/Goccia.Evaluator.Arithmetic.pas, source/units/Goccia.Evaluator.Bitwise.pas
Deleted; their exported arithmetic/bitwise functions removed.
Core implementation usage
source/units/Goccia.VM.pas, source/units/Goccia.Evaluator.pas, source/units/Goccia.AST.Expressions.pas, source/units/Goccia.Evaluator.Assignment.pas, source/units/Goccia.Evaluator.PatternMatching.pas
Opcode handlers, evaluator binary/compound operations, and expression compound-assignment now call Goccia.Arithmetic helpers.
Value helpers & uses updates
source/units/Goccia.Values.ClassHelper.pas, source/units/Goccia.Values.*.pas, source/units/Goccia.Builtins.*.pas
Replaced local comparison/equality/relational logic with calls into Goccia.Arithmetic; updated implementation uses lists.
Primitives helper
source/units/Goccia.Values.Primitives.pas
Added TGocciaBooleanLiteralValue.FromBoolean factory used by updated call sites.
Constant-folding / VM fast-path
source/units/Goccia.Compiler.ConstantFolding.pas, source/units/Goccia.VM.pas
Modulo folding and VM modulo fast path adjusted to preserve negative-zero semantics and call new helpers where applicable.

Test262 Compatibility Roadmap & Runner

Layer / File(s) Summary
Roadmap data
scripts/test262_compatibility_roadmap.json
New JSON mapping of features, flags, harness includes, path segments, syntax, and targets to {status,target} with eligibility metadata.
Harness include map
scripts/test262_harness_map.py
New INCLUDE_MAP and exported AVAILABLE_INCLUDES set for harness includes.
Roadmap-driven checks
scripts/test262_syntax_filter.py
Loads roadmap at import time; replaces hardcoded feature/flag/include/path logic; adds classify_skip_reason and eligibility-derived skip reasons.
Suite clustering & summary
scripts/run_test262_suite.py
Imports harness map; adds MAX_CLUSTER_ITEMS, path_bucket, message_fingerprint, counter_records; tightens per-file JSON recovery to fileName; populates capped summary["clusters"].
CI comment rendering
.github/workflows/pr.yml
test262-comment now conditionally renders a “Compatibility roadmap skips” Markdown table from s.clusters.skipsByTarget (up to five entries).
Runner output change
scripts/run_test262_suite.py
Console failing-tests listing replaced by printing top entries from skip clusters when available.

Binding Patterns & Compiler Refactor

Layer / File(s) Summary
Binding-name utility
source/units/Goccia.AST.BindingPatterns.pas
New unit exposing CollectPatternBindingNames, CollectVarBindingNamesFromNode, CollectVarBindingNamesFromStatements, CollectVarBindingNamesFromNodes.
Compiler destructuring refactor
source/units/Goccia.Compiler.Expressions.pas, source/units/Goccia.Compiler.Statements.pas
Replaced recursive pattern-specific declaration logic with collect-then-declare using the new binding-name utilities.
Hoisting updates
source/units/Goccia.Evaluator.pas
Var-hoisting now uses CollectVarBindingNamesFromStatements/Nodes; removed older local var-collection helpers.
Interfaces unchanged
source/units/Goccia.Compiler.*, source/units/Goccia.Evaluator.pas
Public/interface signatures remain unchanged.

Benchmark Profiling Integration

Layer / File(s) Summary
Profiler integration & CLI
source/app/GocciaBenchmarkRunner.dpr
Adds Goccia.Profiler/Goccia.Profiler.Report; introduces FCanPrintProfile and ProfilingEnabled; Configure() registers profiler CLI options; Validate() normalizes profiler options and forces bytecode mode when profiling.
Lifecycle output & file writing
source/app/GocciaBenchmarkRunner.dpr
AfterExecute() prints opcode/function profile summaries when allowed and writes profiler output to --profile-output (JSON or flamegraph collapsed stacks); ExecuteWithPaths suppresses console profile output when structured stdout is in use; RunBenchmarks forces JobCount := 1 when profiling.
Docs for profiling
docs/benchmarks.md
Adds profiling guidance, supported flags, enforced constraints (profiling forces bytecode and serial execution), and usage examples.

Miscellaneous docs, harness, BigInt & tests

Layer / File(s) Summary
Docs references
docs/adding-built-in-types.md, docs/core-patterns.md, docs/value-system.md, scripts/check-doc-symbols.ts
Updated unit references to point at Goccia.Arithmetic / Goccia.Values.Primitives for specific helper locations.
BigInt parsing helper
source/units/Goccia.Values.BigIntValue.pas
Added TryStringToBigInt implementing ECMAScript-style trim/prefix parsing and safe failure reporting.
BigInt constructor changes
source/units/Goccia.Builtins.GlobalBigInt.pas
GlobalBigInt constructors and conversions now use TryStringToBigInt instead of manual parsing and try/except.
Tests & harness helpers
tests/*, scripts/test262_harness/*
Added/updated tests for BigInt comparisons, BigInt-from-string trimming, modulo negative-zero behavior, ToPrimitive ordering; added assertRelativeDateMs and well-known intrinsic resolver; clarified boxed-BigInt test comment.
Harness map export
scripts/test262_harness_map.py
New mapping used by runner and syntax filter.

Sequence Diagram

sequenceDiagram
    participant Parser as Parser/Compiler
    participant BindingUtil as BindingPatterns (unit)
    participant Evaluator as Evaluator
    participant VM as VM (bytecode)
    participant Arithmetic as Goccia.Arithmetic
    participant Runner as test262 runner

    Parser->>BindingUtil: CollectPatternBindingNames / CollectVarBindingNames...
    BindingUtil-->>Parser: binding name list

    Evaluator->>Arithmetic: CompoundOperations(current, new, operator)
    Arithmetic-->>Evaluator: TGocciaValue result

    VM->>Arithmetic: EvaluateAddition/Division/Bitwise/Relational(...)
    Arithmetic-->>VM: TGocciaValue (handles NaN/Infinity/-0)

    Evaluator->>Arithmetic: IsStrictEqual / LessThan / GreaterThan
    Arithmetic-->>Evaluator: Boolean (call sites wrap via FromBoolean)

    Runner->>Runner: build clusters (path_bucket, message_fingerprint)
    Runner-->>Runner: summary["clusters"]
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: consolidating engine semantics and adding a test262 roadmap, which aligns with the primary objectives of refactoring arithmetic logic and replacing the test262 filtering model.
Description check ✅ Passed The PR description covers the four main objectives (arithmetic consolidation, AST binding patterns, test262 roadmap, profiler-backed benchmarks), documents verification steps, and notes a pre-commit hook limitation with tmp/ files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


Review rate limit: 2/5 reviews remaining, refill in 26 minutes and 17 seconds.

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

@coderabbitai coderabbitai Bot added new feature New feature or request internal Refactoring, CI, tooling, cleanup labels May 2, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

Caution

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

⚠️ Outside diff range comments (2)
source/units/Goccia.Evaluator.pas (2)

1398-1407: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the block-scoped assignment path for var destructuring in loop heads.

AssignVariablePattern(...) bypasses the new AssignBinding/FVarBindings path and evaluates computed keys/defaults against AContext, so nested patterns in for / for await can see the wrong scope. Switch these branches to AssignPattern(..., False) instead.

Proposed fix
-              if AForOfStatement.BindingPattern <> nil then
-                AssignVariablePattern(AForOfStatement.BindingPattern, CurrentValue, AContext)
+              if AForOfStatement.BindingPattern <> nil then
+                AssignPattern(AForOfStatement.BindingPattern, CurrentValue, IterContext, False, DeclarationType)

Apply the same change in EvaluateForAwaitOf.

Also applies to: 1618-1626

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

In `@source/units/Goccia.Evaluator.pas` around lines 1398 - 1407, The
var-destructuring branch in the for/of loop uses
AssignVariablePattern(AForOfStatement.BindingPattern, ...) which bypasses the
block-scoped AssignBinding/FVarBindings path and evaluates computed
keys/defaults against AContext; replace that call with
AssignPattern(AForOfStatement.BindingPattern, CurrentValue, IterContext, False,
DeclarationType) so the destructuring uses the block-scoped assignment path (do
the same replacement in EvaluateForAwaitOf and the other similar branch around
the 1618-1626 region).

4467-4499: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Temp-root RestElements before recursing into nested destructuring.

The array/string fast paths create RestElements and immediately recurse into AssignVariablePattern(...) without rooting it, so a default expression or computed binding can let GC reclaim the array mid-destructuring. The iterable fallback already does the right thing; these branches need the same protection.

Proposed fix
-        RestElements := TGocciaArrayValue.Create;
-        for J := I to ArrayValue.Elements.Count - 1 do
-          RestElements.Elements.Add(ArrayValue.Elements[J]);
-        AssignVariablePattern(
-          TGocciaRestDestructuringPattern(ArrPat.Elements[I]).Argument,
-          RestElements, AContext);
+        RestElements := TGocciaArrayValue.Create;
+        TGarbageCollector.Instance.AddTempRoot(RestElements);
+        try
+          for J := I to ArrayValue.Elements.Count - 1 do
+            RestElements.Elements.Add(ArrayValue.Elements[J]);
+          AssignVariablePattern(
+            TGocciaRestDestructuringPattern(ArrPat.Elements[I]).Argument,
+            RestElements, AContext);
+        finally
+          TGarbageCollector.Instance.RemoveTempRoot(RestElements);
+        end;

Mirror the same rooting in the string branch as well.

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

In `@source/units/Goccia.Evaluator.pas` around lines 4467 - 4499, The RestElements
local is allocated in the array and string fast-paths and then immediately
passed into AssignVariablePattern, which can recurse and let the GC collect the
temporary; root the RestElements just like the iterable fallback does before
recursing. Concretely, in the branches that create RestElements (the block that
uses TGocciaArrayValue.Create and the block that builds RestElements from
TGocciaStringLiteralValue), ensure you root/push RestElements to the GC (or use
the same rooting helper/mechanism used by the iterable fallback) for the
lifetime of the AssignVariablePattern call, and then unroot/pop it afterward;
reference TGocciaArrayValue, TGocciaStringLiteralValue, RestElements,
TGocciaRestDestructuringPattern and AssignVariablePattern when applying the fix.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/pr.yml:
- Around line 969-972: The fingerprint escaping only handles backticks, so any
'|' in clusters.failureFingerprints items will break the Markdown table; update
the sanitization for the variable fingerprint (where fingerprint is derived from
String(item.fingerprint).replaceAll('`', '\\`')) to also escape pipe characters
(replace '|' with '\\|') and any other Markdown-sensitive characters as needed
before composing the table row, keeping the sanitized variable name
(fingerprint) used in the body concatenation.

In `@scripts/test262_compatibility_roadmap.json`:
- Around line 68-71: The mapping for "ArrayBuffer" currently points to the wrong
target "arrays"; update the "ArrayBuffer" entry in
scripts/test262_compatibility_roadmap.json so its "target" value is
"arraybuffer-typedarray" (the target defined as owning ArrayBuffer) to ensure
correct cluster attribution; locate the "ArrayBuffer" JSON object and replace
"arrays" with "arraybuffer-typedarray".

In `@source/units/Goccia.Arithmetic.pas`:
- Around line 689-725: Call ToPrimitive on both operands at the start of
CompareRelationalValues and use those primitive results for all type dispatch
and final numeric conversion: create local variables (e.g., LPrim :=
ALeft.ToPrimitive; RPrim := ARight.ToPrimitive) and replace all occurrences of
ALeft/ARight in the relational type checks (the TGocciaUndefinedLiteralValue,
TGocciaNullLiteralValue, TGocciaStringLiteralValue, TGocciaBigIntValue and the
BigInt-vs-Number branches) with LPrim/RPrim, and finally call
CompareNumberValues(LPrim.ToNumberLiteral, RPrim.ToNumberLiteral) instead of
using the original ALeft/ARight so string-vs-string and BigInt comparisons are
handled correctly before numeric coercion.
- Around line 297-326: In EvaluateModulo, preserve negative zero for exact-zero
remainders: after computing the remainder (currently Result :=
NumberValue(LeftNum.Value - RightNum.Value * Trunc(LeftNum.Value /
RightNum.Value))), store the numeric remainder in a local Double (e.g., rem :=
LeftNum.Value - RightNum.Value * Trunc(LeftNum.Value / RightNum.Value)); if rem
= 0.0 then detect a negative dividend by checking LeftNum.Value < 0.0 or
(LeftNum.Value = 0.0 and (1.0 / LeftNum.Value) < 0.0) and return
NumberValue(-0.0) in that case, otherwise return NumberValue(0.0); otherwise
return NumberValue(rem). Reference: function EvaluateModulo, variables LeftNum,
RightNum, and the NumberValue constructor.

In `@source/units/Goccia.AST.BindingPatterns.pas`:
- Around line 70-79: The centralized collector (CollectVarBindingNamesFromNode)
currently handles TGocciaForOfStatement but omits TGocciaForAwaitOfStatement,
causing names from "for await (var ...)" to be skipped; update
CollectVarBindingNamesFromNode to treat TGocciaForAwaitOfStatement the same as
TGocciaForOfStatement (visit its Left/Variable/Declaration nodes and collect
identifiers into the same VarDecl/DestructDecl/ExportVarDecl paths), and make
the analogous addition in the other mirrored visitor block (the one around the
114-125 region) so both switch/case branches include TGocciaForAwaitOfStatement
handling. Ensure you reference TGocciaForAwaitOfStatement and reuse the existing
handling logic for TGocciaForOfStatement to avoid duplication.

---

Outside diff comments:
In `@source/units/Goccia.Evaluator.pas`:
- Around line 1398-1407: The var-destructuring branch in the for/of loop uses
AssignVariablePattern(AForOfStatement.BindingPattern, ...) which bypasses the
block-scoped AssignBinding/FVarBindings path and evaluates computed
keys/defaults against AContext; replace that call with
AssignPattern(AForOfStatement.BindingPattern, CurrentValue, IterContext, False,
DeclarationType) so the destructuring uses the block-scoped assignment path (do
the same replacement in EvaluateForAwaitOf and the other similar branch around
the 1618-1626 region).
- Around line 4467-4499: The RestElements local is allocated in the array and
string fast-paths and then immediately passed into AssignVariablePattern, which
can recurse and let the GC collect the temporary; root the RestElements just
like the iterable fallback does before recursing. Concretely, in the branches
that create RestElements (the block that uses TGocciaArrayValue.Create and the
block that builds RestElements from TGocciaStringLiteralValue), ensure you
root/push RestElements to the GC (or use the same rooting helper/mechanism used
by the iterable fallback) for the lifetime of the AssignVariablePattern call,
and then unroot/pop it afterward; reference TGocciaArrayValue,
TGocciaStringLiteralValue, RestElements, TGocciaRestDestructuringPattern and
AssignVariablePattern when applying the fix.
🪄 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: e2d548c1-da3d-47b3-bdce-9420b0de40fd

📥 Commits

Reviewing files that changed from the base of the PR and between 4e93403 and 65fc9e5.

📒 Files selected for processing (33)
  • .github/workflows/pr.yml
  • docs/adding-built-in-types.md
  • docs/benchmarks.md
  • docs/core-patterns.md
  • docs/value-system.md
  • scripts/check-doc-symbols.ts
  • scripts/run_test262_suite.py
  • scripts/test262_compatibility_roadmap.json
  • scripts/test262_syntax_filter.py
  • source/app/GocciaBenchmarkRunner.dpr
  • source/units/Goccia.AST.BindingPatterns.pas
  • source/units/Goccia.AST.Expressions.pas
  • source/units/Goccia.Arithmetic.pas
  • source/units/Goccia.Builtins.GlobalObject.pas
  • source/units/Goccia.Builtins.TestingLibrary.pas
  • source/units/Goccia.Compiler.Expressions.pas
  • source/units/Goccia.Compiler.Statements.pas
  • source/units/Goccia.Evaluator.Arithmetic.pas
  • source/units/Goccia.Evaluator.Assignment.pas
  • source/units/Goccia.Evaluator.Bitwise.pas
  • source/units/Goccia.Evaluator.Comparison.pas
  • source/units/Goccia.Evaluator.PatternMatching.pas
  • source/units/Goccia.Evaluator.pas
  • source/units/Goccia.PatternMatching.pas
  • source/units/Goccia.VM.pas
  • source/units/Goccia.Values.ArrayValue.pas
  • source/units/Goccia.Values.ClassHelper.pas
  • source/units/Goccia.Values.MapValue.pas
  • source/units/Goccia.Values.ObjectValue.pas
  • source/units/Goccia.Values.Primitives.pas
  • source/units/Goccia.Values.ProxyValue.pas
  • source/units/Goccia.Values.SetValue.pas
  • tests/built-ins/BigInt/boxed-bigint-operators.js
💤 Files with no reviewable changes (2)
  • source/units/Goccia.Evaluator.Arithmetic.pas
  • source/units/Goccia.Evaluator.Bitwise.pas

Comment thread .github/workflows/pr.yml Outdated
Comment thread scripts/test262_compatibility_roadmap.json
Comment thread source/units/Goccia.Arithmetic.pas
Comment thread source/units/Goccia.Arithmetic.pas Outdated
Comment thread source/units/Goccia.AST.BindingPatterns.pas
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

Suite Timing

Test Runner (interpreted: 8,434 passed; bytecode: 8,434 passed)
Metric Interpreted Bytecode
Total 8434 8434
Passed 8434 ✅ 8434 ✅
Workers 4 4
Test Duration 1.91s 1.90s
Lex (cumulative) 233.1ms 161.1ms
Parse (cumulative) 237.8ms 249.6ms
Compile (cumulative) 205.4ms
Execute (cumulative) 1.84s 1.60s
Engine Total (cumulative) 2.31s 2.22s
Lex (avg/worker) 58.3ms 40.3ms
Parse (avg/worker) 59.4ms 62.4ms
Compile (avg/worker) 51.3ms
Execute (avg/worker) 459.2ms 400.0ms
Engine Total (avg/worker) 576.9ms 554.1ms

Memory

GC rows aggregate the main thread plus all worker thread-local GCs. Test runner worker shutdown frees thread-local heaps in bulk; that shutdown reclamation is not counted as GC collections or collected objects.

Metric Interpreted Bytecode
GC Live 175.13 MiB 170.00 MiB
GC Peak Live 175.13 MiB 170.01 MiB
GC Allocated During Run 178.78 MiB 173.63 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 1 1
GC Collected Objects 83 83
Heap Start Allocated 142.8 KiB 142.8 KiB
Heap End Allocated 1.34 MiB 1.34 MiB
Heap Delta Allocated 1.20 MiB 1.20 MiB
Heap Delta Free 469.1 KiB 469.1 KiB
Benchmarks (interpreted: 407; bytecode: 407)
Metric Interpreted Bytecode
Total 407 407
Workers 4 4
Duration 2.38min 2.32min

Memory

GC rows aggregate the main thread plus all worker thread-local GCs. Benchmark runner performs explicit between-file collections, so collection and collected-object counts can be much higher than the test runner.

Metric Interpreted Bytecode
GC Live 2.73 MiB 2.72 MiB
GC Peak Live 101.76 MiB 59.26 MiB
GC Allocated During Run 13.42 GiB 9.18 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 2,823 2,640
GC Collected Objects 257,465,086 219,950,360
Heap Start Allocated 1.10 MiB 1.10 MiB
Heap End Allocated 1.10 MiB 1.10 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 18 improved · 🔴 246 regressed · 143 unchanged · avg -2.8%
Bytecode: 🟢 11 improved · 🔴 353 regressed · 43 unchanged · avg -9.8%

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

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 2, 2026

test262 Conformance

Metric Value Δ vs main
Total tests 47,420 ±0
Eligible tests 38,704 (81.6%) -325
Eligible tests passing 20,120 (52.0%) +291 (+1.2pp)
Total tests passing 20,120 (42.4%) +291 (+0.6pp)

Areas closest to 100%

Area Pass rate Δ vs main Passing
language/types 90.1% ±0pp 73 / 81
built-ins/Symbol 87.5% -0.2pp 63 / 72
built-ins/Set 86.1% ±0pp 327 / 380

Compatibility roadmap skips

Target Skipped
excluded-syntax 6,315
modules 1,552
atomics-shared-memory 874
binary-data-dataview 854
realms 247

Non-blocking. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached main baseline.

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation spec compliance Mismatch against official JavaScript/TypeScript specification labels May 2, 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.

♻️ Duplicate comments (1)
.github/workflows/pr.yml (1)

959-961: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Escape item.target before composing Markdown table rows.

On Line [960], item.target is inserted raw. If a target contains |, backticks, or newlines, the PR-comment table can render incorrectly.

Proposed fix
+            const escapeMdCell = (value) => String(value)
+              .replaceAll('\\', '\\\\')
+              .replaceAll('|', '\\|')
+              .replaceAll('`', '\\`')
+              .replace(/\r?\n/g, ' ');
...
               for (const item of clusters.skipsByTarget.slice(0, 5)) {
-                body += `| \`${item.target}\` | ${fmt(item.count)} |\n`;
+                const target = escapeMdCell(item.target);
+                body += `| \`${target}\` | ${fmt(item.count)} |\n`;
               }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/pr.yml around lines 959 - 961, Sanitize item.target before
composing the Markdown table row: create an escapedTarget (e.g., in the loop
over clusters.skipsByTarget) by replacing backticks, pipe characters and
newlines (for example .replace(/`/g, '\\`').replace(/\|/g,
'\\|').replace(/\r?\n/g, ' ')) and then use the escapedTarget in the template
(replace `${item.target}` with `${escapedTarget}`) so the table row generation
in the loop over clusters.skipsByTarget remains well-formed.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In @.github/workflows/pr.yml:
- Around line 959-961: Sanitize item.target before composing the Markdown table
row: create an escapedTarget (e.g., in the loop over clusters.skipsByTarget) by
replacing backticks, pipe characters and newlines (for example .replace(/`/g,
'\\`').replace(/\|/g, '\\|').replace(/\r?\n/g, ' ')) and then use the
escapedTarget in the template (replace `${item.target}` with `${escapedTarget}`)
so the table row generation in the loop over clusters.skipsByTarget remains
well-formed.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 56596b13-8010-4971-b81f-e47f090a2c88

📥 Commits

Reviewing files that changed from the base of the PR and between 65fc9e5 and 4d06141.

📒 Files selected for processing (4)
  • .github/workflows/pr.yml
  • scripts/run_test262_suite.py
  • scripts/test262_compatibility_roadmap.json
  • scripts/test262_syntax_filter.py
✅ Files skipped from review due to trivial changes (1)
  • scripts/test262_compatibility_roadmap.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • scripts/test262_syntax_filter.py
  • scripts/run_test262_suite.py

@coderabbitai coderabbitai Bot added the performance Performance improvement label May 2, 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: 1

🧹 Nitpick comments (1)
scripts/test262_harness/wellKnownIntrinsicObjects.js (1)

70-76: ⚡ Quick win

Convert these helpers to arrow functions.

resolveWellKnownIntrinsic and getWellKnownIntrinsicObject should follow the repo’s JS style for scripts/test262_harness/ and be written as arrow functions instead of function declarations. As per coding guidelines, in this repo’s GocciaScript-executed JavaScript under scripts/test262_harness/, use arrow functions only.

♻️ Suggested rewrite
-function resolveWellKnownIntrinsic(source) {
+const resolveWellKnownIntrinsic = (source) => {
   try {
     return Function("return " + source)();
   } catch (exception) {
     return undefined;
   }
-}
+};

 const WellKnownIntrinsicObjects = WellKnownIntrinsicSources.map(([name, source]) => ({
   name,
   source,
   value: resolveWellKnownIntrinsic(source),
 }));

-function getWellKnownIntrinsicObject(key) {
+const getWellKnownIntrinsicObject = (key) => {
   for (const intrinsic of WellKnownIntrinsicObjects) {
     if (intrinsic.name === key) {
       if (intrinsic.value !== undefined) {
         return intrinsic.value;
       }
       throw new Test262Error("this implementation could not obtain " + key);
     }
   }

   throw new Test262Error("unknown well-known intrinsic " + key);
-}
+};

Also applies to: 84-95

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

In `@scripts/test262_harness/wellKnownIntrinsicObjects.js` around lines 70 - 76,
Convert the two function declarations into arrow-function const bindings:
replace the function declaration for resolveWellKnownIntrinsic with a const
resolveWellKnownIntrinsic = (source) => { ... } preserving the try/catch and
return behavior, and likewise replace getWellKnownIntrinsicObject with const
getWellKnownIntrinsicObject = (source) => { ... } keeping its existing logic and
return values; ensure you keep the original function names as const identifiers
so callers still resolve correctly and that no hoisting-dependent code is
affected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/test262_syntax_filter.py`:
- Around line 41-54: The code assumes COMPATIBILITY_ROADMAP["unknownFeature"]
exists which can raise KeyError; update _roadmap_entry and _entry_is_eligible to
use a safe fallback (e.g., COMPATIBILITY_ROADMAP.get("unknownFeature", {}) or a
module-level UNKNOWN_FEATURE = {}) so lookups never index a missing key, and
ensure _entry_is_eligible treats that safe fallback consistently when entry is
None or falsy (use entry.get("status","") and entry.get("eligible") safely).
Reference: functions _roadmap_entry and _entry_is_eligible and the
COMPATIBILITY_ROADMAP lookup for "unknownFeature".

---

Nitpick comments:
In `@scripts/test262_harness/wellKnownIntrinsicObjects.js`:
- Around line 70-76: Convert the two function declarations into arrow-function
const bindings: replace the function declaration for resolveWellKnownIntrinsic
with a const resolveWellKnownIntrinsic = (source) => { ... } preserving the
try/catch and return behavior, and likewise replace getWellKnownIntrinsicObject
with const getWellKnownIntrinsicObject = (source) => { ... } keeping its
existing logic and return values; ensure you keep the original function names as
const identifiers so callers still resolve correctly and that no
hoisting-dependent code is affected.
🪄 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: 12fd88c2-e0aa-453a-83e9-da9de26bfd68

📥 Commits

Reviewing files that changed from the base of the PR and between 4d06141 and 55c6f5c.

📒 Files selected for processing (6)
  • scripts/run_test262_suite.py
  • scripts/test262_compatibility_roadmap.json
  • scripts/test262_harness/assertRelativeDateMs.js
  • scripts/test262_harness/wellKnownIntrinsicObjects.js
  • scripts/test262_harness_map.py
  • scripts/test262_syntax_filter.py
✅ Files skipped from review due to trivial changes (1)
  • scripts/test262_harness_map.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • scripts/test262_compatibility_roadmap.json

Comment thread scripts/test262_syntax_filter.py
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

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

Inline comments:
In `@scripts/test262_syntax_filter.py`:
- Around line 400-401: The current logic short-circuits syntax/negative
classification by extending reasons only when reasons is empty, causing
missing_harness:* to block later syntax checks; update the flow so
check_includes(includes) is always run after syntax/negative classification and
its results merged into reasons regardless of whether reasons is already
populated — modify the block around the reasons variable (the conditional using
"if not reasons") to always call check_includes(includes) and extend or merge
its returned list into reasons so harness-include failures don't preempt
language-semantic classification.

In `@source/units/Goccia.Compiler.ConstantFolding.pas`:
- Around line 42-50: The fast integer path in FoldedModuloValue (function
FoldedModuloValue) uses Trunc(...) mod Trunc(...), which narrows to Int64 and
can overflow; remove that conditional fast path so the function always computes
the remainder using the floating-point routine FMod(ALeft, ARight) (i.e., call
FMod unconditionally) and preserve the subsequent negative-zero adjustment (the
if that sets Result := NegativeZeroFloat when Result = 0.0 and ALeft is negative
or negative-zero). This makes FoldedModuloValue consistent with FMod and the VM
implementation and avoids Int64 narrowing/overflow.

In `@source/units/Goccia.Values.BigIntValue.pas`:
- Line 73: StringToBigInt uses Trim(AValue) which only strips ASCII whitespace
and misses ECMAScript whitespace like U+00A0 and U+FEFF; replace the Trim call
in StringToBigInt so the input is normalized with an ECMA-262 compliant
whitespace trimmer (e.g., call or add a utility like
StrTrimEcma/TrimEcmaWhitespace that removes all StrWhiteSpace code points
including U+00A0 and U+FEFF) instead of Trim(AValue), or augment the trimming
logic to explicitly strip #$00A0 and #$FEFF before parsing; update the
assignment to Text (and any other callers) to use that ECMA-aware trimmer so
BigInt(string) parsing matches the spec.
🪄 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: 50497a0f-2b87-40ee-91ec-a45282f1a2e0

📥 Commits

Reviewing files that changed from the base of the PR and between 55c6f5c and 4183307.

📒 Files selected for processing (9)
  • scripts/test262_syntax_filter.py
  • source/units/Goccia.Arithmetic.pas
  • source/units/Goccia.Builtins.GlobalBigInt.pas
  • source/units/Goccia.Compiler.ConstantFolding.pas
  • source/units/Goccia.VM.pas
  • source/units/Goccia.Values.BigIntValue.pas
  • tests/language/expressions/bigint/bigint-comparison.js
  • tests/language/expressions/modulo/modulo.js
  • tests/language/expressions/type-coercion/comparison-coercion.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • source/units/Goccia.Arithmetic.pas

Comment thread scripts/test262_syntax_filter.py Outdated
Comment thread source/units/Goccia.Compiler.ConstantFolding.pas
Comment thread source/units/Goccia.Values.BigIntValue.pas Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@scripts/test262_syntax_filter.py`:
- Around line 355-358: The current logic checks AVAILABLE_INCLUDES then consults
_roadmap_entry/_entry_is_eligible which can mark an unmapped include eligible;
change the branch so any include not in AVAILABLE_INCLUDES is unconditionally
treated as missing_harness by immediately appending
reasons.append(f"missing_harness:{inc}") (and skipping the roadmap eligibility
check), while preserving the roadmap lookup only inside classify_skip_reason()
for reporting; update the block around the check involving AVAILABLE_INCLUDES,
_roadmap_entry and _entry_is_eligible accordingly.
🪄 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: df550950-7d61-44d6-ba55-1defa756bd3c

📥 Commits

Reviewing files that changed from the base of the PR and between 4183307 and c9ee432.

📒 Files selected for processing (11)
  • docs/adding-built-in-types.md
  • docs/benchmarks.md
  • docs/core-patterns.md
  • docs/value-system.md
  • scripts/test262_syntax_filter.py
  • source/app/GocciaBenchmarkRunner.dpr
  • source/units/Goccia.Compiler.ConstantFolding.pas
  • source/units/Goccia.VM.pas
  • source/units/Goccia.Values.BigIntValue.pas
  • tests/built-ins/BigInt/constructor.js
  • tests/language/expressions/bigint/bigint-comparison.js
✅ Files skipped from review due to trivial changes (2)
  • docs/core-patterns.md
  • source/units/Goccia.VM.pas
🚧 Files skipped from review as they are similar to previous changes (6)
  • docs/value-system.md
  • docs/adding-built-in-types.md
  • docs/benchmarks.md
  • tests/built-ins/BigInt/constructor.js
  • tests/language/expressions/bigint/bigint-comparison.js
  • source/app/GocciaBenchmarkRunner.dpr

Comment thread scripts/test262_syntax_filter.py Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@scripts/test262_syntax_filter.py`:
- Around line 39-42: The constant UNKNOWN_ROADMAP_ENTRY currently hardcodes
"target": "unassigned" and causes _roadmap_entry() to ignore the roadmap's
unknownFeature policy; update the logic so that when creating fallback entries
(the UNKNOWN_ROADMAP_ENTRY usage) you read the roadmap's unknownFeature (or
equivalent field available to _roadmap_entry) and set the entry's "target" to
that value instead of the hardcoded "unassigned" (also apply the same change to
the other fallback at the second occurrence noted). Ensure you still set
"status": "unsupported" but derive "target" from the roadmap input before
returning the fallback entry.
🪄 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: 8d5cfc4f-982d-4f0d-a6c2-d9e352c38cf6

📥 Commits

Reviewing files that changed from the base of the PR and between c9ee432 and 4bd6c15.

📒 Files selected for processing (1)
  • scripts/test262_syntax_filter.py

Comment thread scripts/test262_syntax_filter.py
@frostney frostney merged commit d7a6e37 into main May 2, 2026
14 checks passed
@frostney frostney deleted the t3code/engine-runtime-analysis branch May 2, 2026 10:05
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 internal Refactoring, CI, tooling, cleanup new feature New feature or request performance Performance improvement spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant