Skip to content

Add dynamic import support to the runtime#282

Merged
frostney merged 3 commits into
mainfrom
t3code/dynamic-import-plan
Apr 12, 2026
Merged

Add dynamic import support to the runtime#282
frostney merged 3 commits into
mainfrom
t3code/dynamic-import-plan

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 12, 2026

Summary

  • Added import(specifier) support so dynamic imports now resolve to a Promise and can be used inside functions, conditionals, and callbacks.
  • Propagated module loading through scope creation so nested dynamic imports resolve relative to the importing file.
  • Updated compiler, parser, interpreter, VM, and import.meta handling to recognize the new import flow.
  • Refreshed documentation to describe dynamic import behavior and removed outdated URI/Temporal built-in entries that are no longer exposed.
  • Consolidated built-in test coverage around the currently supported surface, including new dynamic import tests.

Testing

  • Expected verification: ./build.pas testrunner && ./build/TestRunner tests
  • Expected verification for runtime coverage: run the new tests/language/modules/dynamic-import.js case through ./build/TestRunner tests/language/modules/

- Parse and compile `import()` expressions
- Plumb module loading through scopes and closures
- Add bytecode VM support, docs, and tests
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 12, 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: e70fd934-54dd-42d0-a7bd-5bc800006a98

📥 Commits

Reviewing files that changed from the base of the PR and between 3543abd and b9d6264.

📒 Files selected for processing (9)
  • AGENTS.md
  • docs/language-restrictions.md
  • tests/language/modules/dynamic-import.js
  • tests/language/modules/helpers/dynamic-import-caller.js
  • tests/language/modules/helpers/dynamic-import-dep.js
  • units/Goccia.AST.Expressions.pas
  • units/Goccia.Compiler.Expressions.pas
  • units/Goccia.Parser.pas
  • units/Goccia.VM.pas
✅ Files skipped from review due to trivial changes (4)
  • tests/language/modules/helpers/dynamic-import-dep.js
  • tests/language/modules/dynamic-import.js
  • tests/language/modules/helpers/dynamic-import-caller.js
  • AGENTS.md
🚧 Files skipped from review as they are similar to previous changes (4)
  • docs/language-restrictions.md
  • units/Goccia.Parser.pas
  • units/Goccia.Compiler.Expressions.pas
  • units/Goccia.AST.Expressions.pas

📝 Walkthrough

Walkthrough

Adds ECMAScript dynamic import() support across parser, AST, compiler, bytecode, and VM; propagates module-loading callback through scopes/closures; introduces a promise-based runtime evaluation for dynamic imports and accompanying tests and documentation updates.

Changes

Cohort / File(s) Summary
Documentation
AGENTS.md, docs/bytecode-vm.md, docs/design-decisions.md, docs/language-restrictions.md
Added references and text describing dynamic import() semantics, bytecode families, scope-based module-loading propagation, and example usages.
AST Expression Node
units/Goccia.AST.Expressions.pas
Added TGocciaImportCallExpression with Specifier and Evaluate that creates a TGocciaPromiseValue, calls AContext.LoadModule(...), and resolves/rejects the promise with proper error-object mapping.
Parser
units/Goccia.Parser.pas
Recognizes import(<specifier>) as an import-call expression, parses the specifier expression, and disambiguates import(...) as an expression statement.
Compiler
units/Goccia.Compiler.Expressions.pas, units/Goccia.Compiler.pas
New CompileDynamicImport emits OP_DYNAMIC_IMPORT with compiled specifier; DoCompileExpression dispatches TGocciaImportCallExpression accordingly.
Bytecode Infrastructure
units/Goccia.Bytecode.pas, units/Goccia.Bytecode.OpCodeNames.pas
Bumped GOCCIA_FORMAT_VERSION 11→12; added OP_DYNAMIC_IMPORT = 171 and opcode-name mapping.
VM Execution
units/Goccia.VM.pas
Implemented OP_DYNAMIC_IMPORT handler: creates/roots a promise, calls ImportModuleValue (new overload accepting referrer), resolves/rejects with error-object conversion, and sets result register.
Scope & Runtime
units/Goccia.Scope.pas, units/Goccia.Interpreter.pas, units/Goccia.Values.FunctionValue.pas
Added TGocciaScope.LoadModule callback field/property and inheritance to child scopes; interpreter binds its LoadModule to global scope; functions inherit LoadModule from closure instead of clearing it.
Error Messaging
units/Goccia.Error.Suggestions.pas
Added SSuggestDynamicImportSyntax resource string for dynamic import usage.
Tests & Helpers
tests/language/modules/dynamic-import.js, tests/language/modules/helpers/*
Added comprehensive tests for dynamic import (await/.then, computed specifiers, conditional/async usage, JSON modules, cache identity) plus helper modules (dynamic-import-caller.js, dynamic-import-dep.js).

Sequence Diagram

sequenceDiagram
    participant Parser
    participant Compiler
    participant VM
    participant ModuleLoader
    participant Promise

    Parser->>Compiler: emit TGocciaImportCallExpression
    Compiler->>Compiler: compile specifier -> register B
    Compiler->>VM: emit OP_DYNAMIC_IMPORT (dest=A, spec=B)
    VM->>VM: create TGocciaPromiseValue
    VM->>ModuleLoader: LoadModule(specifier, referrer)
    ModuleLoader-->>VM: Module object / throws error
    VM->>Promise: Resolve with Module.GetNamespaceObject / Reject with ErrorObject
    VM-->>Caller: return Promise in register A
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description covers the main changes and testing approach, though testing checklist items are incomplete and lack detail on verification completeness. Add specific test results or confirmation that all checklist items were completed; clarify whether documentation updates and regression testing were fully verified.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly describes the main feature being added: dynamic import support to the runtime.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation new feature New feature or request spec compliance Mismatch against official JavaScript/TypeScript specification labels Apr 12, 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: 3

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

Inline comments:
In `@tests/language/modules/dynamic-import.js`:
- Around line 3-71: Add a new test in the "dynamic import()" suite that verifies
the cross-module exported-function regression: create a helper module (e.g.,
helpers/caller.js) that exports a function callAndImport which does return
import("./dep.js") (where dep.js exports a known value), then in the test
require/import helpers/caller.js and invoke callAndImport() from this test file
and assert the resolved module's exported value; this proves resolution is done
relative to the caller module rather than the importer. Ensure the new helper
dep.js exports a distinctive value (e.g., exported constant) and the test name
describes the regression (e.g., "resolves relative to exporting module when
import() is inside exported function").

In `@units/Goccia.VM.pas`:
- Around line 5219-5220: The import resolution currently calls
DynImportPromise.Resolve(ImportModuleValue(RegisterToValue(FRegisters[B]).ToStringLiteral.Value))
which uses FCurrentModuleSourcePath and bypasses VM coercion; change to build
the request with VMRegisterToECMAStringFast(FRegisters[B]).Value and call an
ImportModuleValue overload that accepts a referrer path (use
Template.DebugInfo.SourceFile when present, otherwise fall back to
FCurrentModuleSourcePath), then pass that result into DynImportPromise.Resolve
so imports resolve against the closure’s source module and use the VM’s normal
ToString coercion path; add the new ImportModuleValue(referrerPath) overload to
accept and use the referrer.
- Around line 5221-5228: The catch-all Exception branch in the dyn import
handler is converting specialized exceptions into a generic Error when calling
DynImportPromise.Reject; update the except block in the dynamic import handling
so it mirrors the outer opcode loop’s typed mappings: detect TGocciaTypeError,
TGocciaReferenceError, TGocciaSyntaxError (and any other TGoccia* error classes
used elsewhere) and call DynImportPromise.Reject with the corresponding
specialized error object instead of CreateErrorObject(ERROR_NAME, E.Message),
only falling back to the generic CreateErrorObject for unknown Exception types;
reference the existing patterns used for EGocciaBytecodeThrow, TGocciaThrowValue
and CreateErrorObject to implement the same typed mapping.
🪄 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: 55baa236-f909-49e3-8ad9-848501cf67d8

📥 Commits

Reviewing files that changed from the base of the PR and between 130c3dc and 3543abd.

📒 Files selected for processing (16)
  • AGENTS.md
  • docs/bytecode-vm.md
  • docs/design-decisions.md
  • docs/language-restrictions.md
  • tests/language/modules/dynamic-import.js
  • units/Goccia.AST.Expressions.pas
  • units/Goccia.Bytecode.OpCodeNames.pas
  • units/Goccia.Bytecode.pas
  • units/Goccia.Compiler.Expressions.pas
  • units/Goccia.Compiler.pas
  • units/Goccia.Error.Suggestions.pas
  • units/Goccia.Interpreter.pas
  • units/Goccia.Parser.pas
  • units/Goccia.Scope.pas
  • units/Goccia.VM.pas
  • units/Goccia.Values.FunctionValue.pas

Comment thread tests/language/modules/dynamic-import.js
Comment thread units/Goccia.VM.pas Outdated
Comment thread units/Goccia.VM.pas
frostney and others added 2 commits April 12, 2026 15:42
…test coverage

- Use Template.DebugInfo.SourceFile as referrer in OP_DYNAMIC_IMPORT so
  dynamic imports inside exported functions resolve relative to the defining
  module, not the calling module
- Use VMRegisterToECMAStringFast for specifier coercion in the VM path
- Preserve typed error classes (SyntaxError, TypeError, ReferenceError) in
  rejection instead of collapsing to plain Error
- Add cross-module regression test with helper modules that prove resolution
  stays relative to the exporting module

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

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 5218 5218
Tests Passed 5177 ✅ 5218 ✅
Tests Skipped 41 0
Tests Test Duration 278.2ms 351.1ms
Tests Lex 80.4ms 67.9ms
Tests Parse 104.6ms 130.7ms
Tests Compile 83.6ms
Tests Execute 292.3ms 387.3ms
Tests Engine Total 477.4ms 669.5ms
Benchmarks Total 364 364
Benchmarks Duration 9.69min 8.80min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results

364 benchmarks

Interpreted: 🟢 196 improved · 🔴 117 regressed · 51 unchanged · avg +2.2%
Bytecode: 🟢 138 improved · 🔴 116 regressed · 110 unchanged · avg +0.4%

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

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.

@frostney frostney merged commit c925727 into main Apr 12, 2026
9 checks passed
@frostney frostney deleted the t3code/dynamic-import-plan branch April 12, 2026 15:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation new feature New feature or request spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant