Skip to content

Centralize CLI source pipeline handling#685

Open
frostney wants to merge 5 commits into
mainfrom
t3code/1313e9ad
Open

Centralize CLI source pipeline handling#685
frostney wants to merge 5 commits into
mainfrom
t3code/1313e9ad

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented May 25, 2026

Summary

  • Add Goccia.CLI.SourcePipelineResult as the CLI-owned wrapper around source pipeline parse results.
  • Add Goccia.CLI.SourceMaps for shared CLI source-map writing.
  • Centralize CLI parse warnings and coverage source registration while keeping bytecode compilation separate.
  • Transfer generated source lines from the source pipeline without cloning, keep implementation terminology out of CONTEXT.md, and document the CLI helper boundary in docs/architecture.md.

Testing

  • Verified no regressions and confirmed the new feature or bugfix in end-to-end JavaScript/TypeScript tests
  • Updated documentation
  • Optional: Verified no regressions and confirmed the new feature or bugfix in native Pascal tests (if AST, scope, evaluator, or value types changed)
  • Optional: Verified no benchmark regressions or confirmed benchmark coverage for the change

Commands run:

  • ./format.pas --check
  • git diff --check
  • ./build.pas clean loader bundler testrunner benchmarkrunner repl
  • ./fixtures/ffi/build.sh
  • ./build/GocciaTestRunner tests --no-progress

@vercel
Copy link
Copy Markdown

vercel Bot commented May 25, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Preview May 25, 2026 6:26pm

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 25, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces a CLI-specific source pipeline result wrapper and shared source-map output procedure, then refactors five CLI applications to use them. The abstraction consolidates warning display, resource ownership management, and coverage registration, replacing scattered per-application logic with reusable components.

Changes

CLI Source Pipeline Result and Application Updates

Layer / File(s) Summary
CLI Pipeline Result Foundation and Shared Methods
source/app/Goccia.CLI.SourcePipelineResult.pas, source/units/Goccia.SourcePipeline.pas
TGocciaCLISourcePipelineResult wraps TGocciaSourcePipeline.Parse output and manages owned resources (program node, source map, generated source lines). Its static Parse method parses, prints warnings, and transfers ownership; RegisterCoverageSource registers execution lines and cloned source maps. TGocciaSourcePipeline gains TakeGeneratedSourceLines to transfer ownership.
Source Map Output Policy
source/app/Goccia.CLI.SourceMaps.pas
WriteSourceMapIfAvailable centralizes source-map file writing: sets filename/source-path, saves to the output path, and optionally prints a status message.
Script Loader Source Parsing and Coverage
source/app/GocciaScriptLoader.dpr
Script Loader removes the ParseSource helper and refactors WriteSourceMapIfEnabled to delegate to WriteSourceMapIfAvailable. ExecuteBytecodeFromSource now uses TGocciaCLISourcePipelineResult.Parse for unified parsing, coverage registration via RegisterCoverageSource, and resource cleanup.
Bundler Source Compilation and Output
source/app/GocciaBundler.dpr
Bundler removes ParseSource helper, refactors WriteSourceMapIfEnabled to compute output paths and delegate to WriteSourceMapIfAvailable, and updates CompileSource to parse via the new CLI result and manage cleanup consistently.
Test Runner and Benchmark Runner Migration
source/app/GocciaTestRunner.dpr, source/app/GocciaBenchmarkRunner.dpr
Test Runner and Benchmark Runner update bytecode collection/execution to use TGocciaCLISourcePipelineResult.Parse, extract timing from the result, delegate coverage registration to RegisterCoverageSource, and compile from ProgramNode.
REPL Bytecode Execution Migration
source/app/GocciaREPL.dpr
REPL updates bytecode execution to parse via TGocciaCLISourcePipelineResult.Parse, extract timing, compile from ProgramNode, and clean up in a finally block.
Architecture Documentation
docs/architecture.md
Documentation describes the CLI pipeline result type's responsibilities and identifies Goccia.CLI.SourceMaps as the owner of shared CLI source-map output policy.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • frostney/GocciaScript#289: The retrieved PR adds the TC39 v3 Goccia.SourceMap implementation and rewires ScriptLoader's --source-map flow, and the main PR further refactors ScriptLoader to use the new TGocciaCLISourcePipelineResult and delegate .map emission to Goccia.CLI.SourceMaps.
  • frostney/GocciaScript#322: The retrieved PR's new GocciaBundler.dpr CLI compiles sources and optionally writes .map files, and the main PR directly refactors GocciaBundler.dpr's source pipeline/SourceMap emission to use TGocciaCLISourcePipelineResult and WriteSourceMapIfAvailable.
  • frostney/GocciaScript#62: Both PRs modify the benchmark runner's bytecode collection flow (e.g., CollectBenchmarkFileBytecode)—the main PR switches it to TGocciaCLISourcePipelineResult.Parse output for compilation, while the retrieved PR refactors bytecode-result plumbing and resource/lifetime handling.

Suggested labels

internal, new feature, documentation

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Centralize CLI source pipeline handling' accurately captures the main objective of this PR, which is to consolidate CLI-specific source pipeline result handling through new wrapper units.
Description check ✅ Passed The PR description comprehensively covers all template sections: it summarizes the key changes (new units for CLI source pipeline and source maps, centralization of warnings/coverage registration), notes constraints (bytecode compilation kept separate), documents the architectural boundary, and includes a thorough testing checklist with specific commands executed.
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.


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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

Suite Timing

Test Runner (interpreted: 9,798 passed; bytecode: 9,798 passed)
Metric Interpreted Bytecode
Total 9798 9798
Passed 9798 ✅ 9798 ✅
Workers 4 4
Test Duration 3.11s 3.21s
Lex (cumulative) 447.1ms 455.4ms
Parse (cumulative) 302.3ms 307.2ms
Compile (cumulative) 631.2ms
Execute (cumulative) 3.09s 2.99s
Engine Total (cumulative) 3.84s 4.39s
Lex (avg/worker) 111.8ms 113.8ms
Parse (avg/worker) 75.6ms 76.8ms
Compile (avg/worker) 157.8ms
Execute (avg/worker) 771.5ms 748.0ms
Engine Total (avg/worker) 958.8ms 1.10s

Memory

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

Metric Interpreted Bytecode
GC Live 280.98 MiB 275.22 MiB
GC Peak Live 280.99 MiB 275.23 MiB
GC Allocated During Run 285.47 MiB 279.72 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 1 1
GC Collected Objects 88 88
Heap Start Allocated 159.1 KiB 159.1 KiB
Heap End Allocated 1.53 MiB 1.53 MiB
Heap Delta Allocated 1.37 MiB 1.37 MiB
Heap Delta Free 448.9 KiB 448.9 KiB
Benchmarks (interpreted: 407; bytecode: 407)
Metric Interpreted Bytecode
Total 407 407
Workers 4 4
Duration 2.50min 2.24min

Memory

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

Metric Interpreted Bytecode
GC Live 3.93 MiB 3.93 MiB
GC Peak Live 120.49 MiB 68.09 MiB
GC Allocated During Run 18.86 GiB 9.14 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 2,824 2,659
GC Collected Objects 344,243,776 209,361,922
Heap Start Allocated 1.27 MiB 1.27 MiB
Heap End Allocated 1.27 MiB 1.27 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 399 improved · 🔴 5 regressed · 3 unchanged · avg +42.2%
Bytecode: 🟢 26 improved · 🔴 343 regressed · 38 unchanged · avg -6.6%

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

Deterministic profile diff

Deterministic profile diff: no significant changes.

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 changed the title Centralize CLI parsed source handling Centralize CLI source pipeline handling May 25, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

test262 Conformance

Category Run Passed Δ Pass Failed Pass-rate Δ Rate
built-ins 23,449 16,067 +1 7,377 68.5% ±0pp
harness 116 72 ±0 44 62.1% ±0pp
intl402 3,324 935 ±0 2,389 28.1% ±0pp
language 23,635 14,433 ±0 9,202 61.1% ±0pp
staging 1,484 571 ±0 910 38.5% ±0pp
total 52,008 32,078 +1 19,922 61.7% ±0pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
built-ins/WeakMap 99.3% ±0pp 140 / 141
built-ins/WeakSet 98.8% ±0pp 84 / 85
language/future-reserved-words 98.1% ±0pp 53 / 54
Per-test deltas (+1 / -0)

Newly passing (1):

  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js

Steady-state failures are non-blocking; regressions vs the cached main baseline (lower total pass count, or any PASS → non-PASS transition) fail the conformance gate. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached main baseline.

@frostney frostney marked this pull request as ready for review May 25, 2026 18:28
@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation new feature New feature or request internal Refactoring, CI, tooling, cleanup labels May 25, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@source/app/GocciaBundler.dpr`:
- Around line 104-105: WriteSourceMapIfAvailable currently defaults
MapOutputPath from the original source path (AFileName/SourceName) which causes
.map files to be written beside sources instead of beside the emitted bytecode;
change the default MapOutputPath logic to derive from the resolved/emitted
bytecode output path (the same path ResolveOutputPath/EmitGBC or whatever
produces the .gbc uses) so the .map is written next to the generated .gbc;
update the call site that passes MapOutputPath (where
WriteSourceMapIfAvailable(ASourceMap, MapOutputPath, SourceName, ... ) is
invoked) to compute MapOutputPath from the resolved output filename for the
bytecode (not SourceName/AFileName) and ensure the code that constructs the
default map filename simply replaces the .gbc extension on that resolved output
path with .map.
🪄 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: 8d3547d0-e7e7-40e6-a6e4-cb149dd4e9cd

📥 Commits

Reviewing files that changed from the base of the PR and between 1e4617a and 6edd9d0.

📒 Files selected for processing (9)
  • docs/architecture.md
  • source/app/Goccia.CLI.SourceMaps.pas
  • source/app/Goccia.CLI.SourcePipelineResult.pas
  • source/app/GocciaBenchmarkRunner.dpr
  • source/app/GocciaBundler.dpr
  • source/app/GocciaREPL.dpr
  • source/app/GocciaScriptLoader.dpr
  • source/app/GocciaTestRunner.dpr
  • source/units/Goccia.SourcePipeline.pas

Comment on lines +104 to +105
WriteSourceMapIfAvailable(ASourceMap, MapOutputPath, SourceName,
not GIsWorkerThread);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Default the .map path from the emitted bytecode path, not the source path.

With --source-map but no explicit path, this still derives the map from AFileName, so renamed outputs and directory outputs write .map files beside the source instead of beside the generated .gbc. That makes the delegated source-map policy inconsistent with ResolveOutputPath(...) and can fail when the source tree is not writable.

Suggested fix
 procedure TBundlerApp.WriteSourceMapIfEnabled(
   const ASourceMap: TGocciaSourceMap; const AFileName: string);
 var
   MapOutputPath, SourceName: string;
 begin
   if not FSourceMap.Present then
     Exit;
+  SourceName := ResolveOutputPath(AFileName);
   MapOutputPath := FSourceMap.ValueOr('');
   if MapOutputPath = '' then
-  begin
-    if AFileName = STDIN_FILE_NAME then
-      MapOutputPath := ResolveOutputPath(AFileName) + EXT_MAP
-    else
-      MapOutputPath := AFileName + EXT_MAP;
-  end;
-  SourceName := AFileName;
-  if (SourceName = STDIN_FILE_NAME) and FOutputPath.Present then
-    SourceName := FOutputPath.Value;
+    MapOutputPath := SourceName + EXT_MAP;
   WriteSourceMapIfAvailable(ASourceMap, MapOutputPath, SourceName,
     not GIsWorkerThread);
 end;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@source/app/GocciaBundler.dpr` around lines 104 - 105,
WriteSourceMapIfAvailable currently defaults MapOutputPath from the original
source path (AFileName/SourceName) which causes .map files to be written beside
sources instead of beside the emitted bytecode; change the default MapOutputPath
logic to derive from the resolved/emitted bytecode output path (the same path
ResolveOutputPath/EmitGBC or whatever produces the .gbc uses) so the .map is
written next to the generated .gbc; update the call site that passes
MapOutputPath (where WriteSourceMapIfAvailable(ASourceMap, MapOutputPath,
SourceName, ... ) is invoked) to compute MapOutputPath from the resolved output
filename for the bytecode (not SourceName/AFileName) and ensure the code that
constructs the default map filename simply replaces the .gbc extension on that
resolved output path with .map.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant