Skip to content

Add --source-type CLI flag and config to load entry as a module#480

Merged
frostney merged 3 commits into
mainfrom
t3code/source-type-flag
Apr 30, 2026
Merged

Add --source-type CLI flag and config to load entry as a module#480
frostney merged 3 commits into
mainfrom
t3code/source-type-flag

Conversation

@frostney
Copy link
Copy Markdown
Owner

Summary

  • Adds --source-type=script|module (and matching goccia.json "source-type") on every CLI that calls AddEngineOptions: GocciaScriptLoader, GocciaTestRunner, GocciaBenchmarkRunner, GocciaBundler, GocciaREPL. Default is script, preserving existing behavior.
  • New TGocciaSourceType = (stScript, stModule) on TGocciaEngine. When set to stModule, Execute runs the entry program in a fresh skModule scope with this = undefined, mirroring the semantics imported modules already get from TGocciaModuleLoader (ES2026 §16.2.1.6.4). import.meta.url resolves and top-level this no longer aliases globalThis.
  • EvaluateModuleBody changes from procedure to function returning TGocciaValue so the test runner can still observe the runTests(...) completion value when the entry runs as a module. Existing module loader call sites discard the return.
  • New TGocciaBytecodeExecutor.RunModuleInScope lets non-Engine.Execute callers (the script loader's bytecode-from-source/file paths plus the test and benchmark runners) honor the flag without losing their per-phase timing optimizations.

Test plan

  • ./build.pas clean dev build of all five binaries
  • ./build/GocciaTestRunner tests --asi --unsafe-ffi --no-progress (interpreted) — 8233/8279 (5 pre-existing FFI fixture failures, unrelated)
  • ./build/GocciaTestRunner tests --asi --unsafe-ffi --mode=bytecode --no-progress — 8274/8279 (same 5 pre-existing failures)
  • All Pascal unit tests pass (build/Goccia.*.Test)
  • ./format.pas --check passes
  • New tests/language/source-type/ directory with a per-directory goccia.json and assertions on top-level this + import.meta — 6/6 tests pass in both interpreted and bytecode mode
  • Manual smoke: CLI flag, config file, CLI-overrides-config priority, invalid-value error, --help listing all five binaries

🤖 Generated with Claude Code

frostney and others added 2 commits April 30, 2026 04:53
Threads a new TGocciaSourceType (stScript, stModule) enum through the
engine and CLI options layer. When source-type=module, Engine.Execute
runs the entry program in a fresh skModule scope with this=undefined,
matching the semantics imported modules already get from the module
loader. EvaluateModuleBody changes from procedure to function so the
test runner can still observe the runTests(...) result, and the
bytecode executor exposes RunModuleInScope so script loader, test
runner, and benchmark runner bytecode paths honour the flag too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds SourceType to the embedding guide's "Preprocessors and
Compatibility" table alongside Preprocessors/Compatibility/StrictTypes
and includes "source-type" in the goccia.json example so the option
appears next to the other engine flags it sits beside in CLI.Options.

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

vercel Bot commented Apr 30, 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 Apr 30, 2026 8:10am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 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: 2b7075f0-06ce-4a95-b104-68cbe6905468

📥 Commits

Reviewing files that changed from the base of the PR and between 6452316 and 5dc211d.

📒 Files selected for processing (2)
  • docs/embedding.md
  • source/app/Goccia.CLI.Application.pas
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/embedding.md

📝 Walkthrough

Walkthrough

Adds a new engine source mode (--source-type / goccia.json "source-type") with module and script values. Module mode runs entries in a fresh module scope (skModule) with top-level this set to undefined; core executors now return module evaluation values and runners respect per-file/resolved source-type.

Changes

Cohort / File(s) Summary
Documentation
AGENTS.md, docs/build-system.md, docs/embedding.md
Documented the new --source-type=module CLI flag and goccia.json "source-type" key; added embedding guidance about stModule vs stScript, this binding, and persistence across Execute calls.
CLI & Config
source/shared/CLI.Options.pas, source/app/Goccia.CLI.Application.pas
Added TGocciaSourceType enum and SourceType CLI/config option; implemented resolver logic that validates per-file config strings (accepting module/script), emits warnings on invalid values, and applies precedence (CLI → per-file → root → default).
Core engine / executor API
source/units/Goccia.Executor.pas, source/units/Goccia.Interpreter.pas, source/units/Goccia.Engine.pas, source/units/Goccia.Engine.Backend.pas
Changed EvaluateModuleBody from procedure to function returning TGocciaValue (abstract and implementations); added TGocciaSourceType and TGocciaEngine.SourceType; Execute now branches on SourceType and runs module-mode code in a fresh child scope with this=undefined; added RunModuleInScope helper in backend.
Module loader / callbacks
source/units/Goccia.Modules.Loader.pas
Updated TGocciaModuleBodyEvaluator type to return TGocciaValue; clarified documentation of module return semantics and import behavior.
Bytecode / application runners
source/app/GocciaScriptLoader.dpr, source/app/GocciaTestRunner.dpr, source/app/GocciaBenchmarkRunner.dpr
Added helpers (RunBytecodeModule/RunBytecodeTestModule/RunBytecodeBenchmarkModule) to create module child scopes (skModule), set ThisValue := undefined, and execute bytecode in-module when Engine.SourceType = stModule; wired these into existing bytecode execution paths.
Tests
tests/language/source-type/goccia.json, tests/language/source-type/this-binding.js, tests/language/source-type/import-meta.js
Added fixtures running in module mode and tests asserting top-level this is undefined and import.meta/import.meta.url behavior.

Sequence Diagram

sequenceDiagram
    participant CLI as CLI Parser
    participant Resolver as ResolveSourceTypeOption
    participant Engine as TGocciaEngine
    participant Executor as TGocciaExecutor
    participant Scope as TGocciaScope

    CLI->>Resolver: parse --source-type / per-file config / root config
    Resolver->>Resolver: validate (module|script) or warn + fallback
    Resolver->>Engine: set Engine.SourceType

    alt Script mode
        Engine->>Executor: ExecuteProgram in GlobalScope
        Executor->>Executor: run top-level statements (script semantics)
        Executor-->>Engine: completion
    else Module mode
        Engine->>Scope: create child scope (skModule)
        Scope->>Scope: set ThisValue := undefined
        Engine->>Executor: EvaluateModuleBody with module scope
        Executor->>Executor: evaluate statements, capture return value
        Executor-->>Engine: return TGocciaValue
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

documentation

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding a --source-type CLI flag and config option to load entry as a module. It is concise, specific, and clearly summarizes the primary objective.
Description check ✅ Passed The description comprehensively covers the summary of changes, test plan with verified results, and implementation details including the new TGocciaSourceType enum, module-scoped execution semantics, EvaluateModuleBody function conversion, and bytecode executor changes. All required template sections are addressed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 31 minutes and 28 seconds.

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 8358 8358
Tests Passed 8317 ✅ 8358 ✅
Tests Skipped 41 0
Tests Workers 4 4
Tests Test Duration 1.80s 1.90s
Tests Lex (cumulative) 200.6ms 136.1ms
Tests Parse (cumulative) 297.6ms 327.7ms
Tests Compile (cumulative) 226.3ms
Tests Execute (cumulative) 1.48s 1.60s
Tests Engine Total (cumulative) 1.98s 2.29s
Tests Lex (avg/worker) 50.1ms 34.0ms
Tests Parse (avg/worker) 74.4ms 81.9ms
Tests Compile (avg/worker) 56.6ms
Tests Execute (avg/worker) 370.3ms 398.8ms
Tests Engine Total (avg/worker) 494.8ms 571.4ms
Benchmarks Total 407 407
Benchmarks Workers 4 4
Benchmarks Duration 2.49min 2.40min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 12 improved · 🔴 323 regressed · 72 unchanged · avg -5.6%
Bytecode: 🟢 91 improved · 🔴 59 regressed · 257 unchanged · avg +1.4%

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

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 marked this pull request as ready for review April 30, 2026 07:53
@coderabbitai coderabbitai Bot added new feature New feature or request spec compliance Mismatch against official JavaScript/TypeScript specification internal Refactoring, CI, tooling, cleanup labels Apr 30, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

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

Inline comments:
In `@docs/embedding.md`:
- Around line 436-447: Update the docs to explicitly state that when
TGocciaEngine.SourceType is set to stModule, each call to TGocciaEngine.Execute
runs in a fresh module scope (skModule) so top-level bindings are not preserved
across repeated Execute calls; reference the earlier "long-lived engine" example
and clarify that behavior differs from default script mode where the engine
reuses the top-level scope, and suggest using script mode (stScript) or an
explicit persistence mechanism if callers expect bindings to persist between
Execute invocations.

In `@source/app/Goccia.CLI.Application.pas`:
- Around line 443-448: The current block that uses FindConfigEntry to parse
'source-type' silently treats any non-'module' value as 'script'; change it to
explicitly validate ValueStr (case-insensitive) against allowed enums ('module'
and 'script') and reject unknown values instead of defaulting to script—use the
same enum-parsing/validation behavior as the CLI/root-config code: if ValueStr =
'module' then return Goccia.Engine.stModule, if ValueStr = 'script' then return
Goccia.Engine.stScript, otherwise raise an error or propagate a configuration
parse failure (with a clear message) so invalid per-file source-type entries are
not silently accepted.
🪄 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: aa8220d7-5fa5-4e72-b2fb-888e29965c0d

📥 Commits

Reviewing files that changed from the base of the PR and between 168e0e9 and 6452316.

📒 Files selected for processing (16)
  • AGENTS.md
  • docs/build-system.md
  • docs/embedding.md
  • source/app/Goccia.CLI.Application.pas
  • source/app/GocciaBenchmarkRunner.dpr
  • source/app/GocciaScriptLoader.dpr
  • source/app/GocciaTestRunner.dpr
  • source/shared/CLI.Options.pas
  • source/units/Goccia.Engine.Backend.pas
  • source/units/Goccia.Engine.pas
  • source/units/Goccia.Executor.pas
  • source/units/Goccia.Interpreter.pas
  • source/units/Goccia.Modules.Loader.pas
  • tests/language/source-type/goccia.json
  • tests/language/source-type/import-meta.js
  • tests/language/source-type/this-binding.js

Comment thread docs/embedding.md
Comment thread source/app/Goccia.CLI.Application.pas
Two fixes:

* docs/embedding.md: spell out that stModule allocates a fresh
  skModule scope per Execute call, so top-level let/const/class
  declarations do not persist across Execute invocations the way
  they do in default stScript mode (the long-lived engine pattern).
  Suggest staying on stScript or going through the global scope
  (RegisterGlobal / DefineLexicalBinding) when persistence is wanted.

* source/app/Goccia.CLI.Application.pas: per-file goccia.json values
  for "source-type" are now validated case-insensitively. Unknown
  values emit a stderr warning and fall back to stScript instead of
  silently flipping to script. CLI flag and root-config values were
  already validated by TGocciaEnumOption.Apply, so this just plugs
  the per-file gap without changing the existing fail-fast behavior
  on the other layers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai coderabbitai Bot added the documentation Improvements or additions to documentation label Apr 30, 2026
@frostney frostney merged commit c37ba01 into main Apr 30, 2026
12 checks passed
@frostney frostney deleted the t3code/source-type-flag branch April 30, 2026 08:18
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 spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant