Skip to content

Add .txt and .md text asset imports#190

Merged
frostney merged 2 commits into
mainfrom
t3code/asset-text-imports
Apr 6, 2026
Merged

Add .txt and .md text asset imports#190
frostney merged 2 commits into
mainfrom
t3code/asset-text-imports

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 6, 2026

Summary

  • Adds module loading support for text assets with .txt and .md extensions.
  • Exposes text assets as named exports: content for raw UTF-8 text and metadata for frozen file metadata.
  • Expands extensionless module resolution to include structured data and text asset extensions.
  • Updates docs, style guidance, and language restrictions to describe the new import surface.
  • Adds JS and Pascal test coverage for UTF-8 text asset imports, namespace imports, and metadata fields.

Testing

  • Added/updated Pascal coverage in units/Goccia.Modules.ContentProvider.Test.pas for loading UTF-8 .txt modules.
  • Added JS end-to-end coverage in tests/language/modules/text-import.js for content, metadata, extensionless resolution, and namespace imports.
  • New helper fixtures added under tests/language/modules/helpers/ for .txt and .md asset imports.

Summary by CodeRabbit

Release Notes

  • New Features

    • Added support for importing .txt and .md files as modules with named exports for file content and metadata (including file path, name, extension, and byte length)
    • Extensionless imports now resolve to text asset files (e.g., ./note resolves to ./note.txt)
  • Documentation

    • Updated code style and design decision documentation to reflect expanded module import support

- Resolve `.txt` and `.md` through module imports
- Expose `content` and frozen `metadata` exports
- Update docs and tests for text asset loading
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 6, 2026

📝 Walkthrough

Walkthrough

Extended GocciaScript module system to support text-asset imports from .txt and .md files. Added new file extension constants, a text-asset loader implementation, updated the resolver to probe text-asset extensions, and added comprehensive test coverage and documentation.

Changes

Cohort / File(s) Summary
Documentation
AGENTS.md, README.md, docs/code-style.md, docs/design-decisions.md, docs/embedding.md, docs/language-restrictions.md, tests/language/modules/helpers/guide.md
Updated code-style conventions and documentation to describe text-asset module imports (.txt, .md) and their content/metadata named exports. Expanded module-resolver extension probing to include text/structured-data extensions.
File Extension Constants & Properties
units/Goccia.FileExtensions.pas, units/Goccia.Constants.PropertyNames.pas
Added EXT_TXT, EXT_MD file extension constants; introduced ModuleImportExtensions array and IsTextAssetExtension function; added property name constants (PROP_CONTENT, PROP_PATH, PROP_FILE_NAME, PROP_EXTENSION) for metadata object composition.
Module Resolution & Loading
units/Goccia.Modules.Resolver.pas, units/Goccia.Modules.Loader.pas
Modified resolver to use ModuleImportExtensions instead of ScriptExtensions; implemented new LoadTextAssetModule method in loader to read UTF-8 content, construct frozen metadata objects, and export content and metadata properties.
Tests
tests/language/modules/text-import.js, tests/language/modules/helpers/note.txt, units/Goccia.Modules.ContentProvider.Test.pas
Added Jest test suite validating text-asset imports with named and namespace syntax, extensionless resolution, and metadata object structure; created test fixture files; implemented unit test for UTF-8 text-asset loading with metadata assertions.

Sequence Diagram

sequenceDiagram
    participant Client as Client Code
    participant Resolver as TGocciaModuleResolver
    participant Loader as TGocciaModuleLoader
    participant ContentProvider as TGocciaContentProvider
    participant Module as TGocciaModule
    
    Client->>Resolver: Resolve "./note.txt" (or "./note")
    Resolver->>Resolver: Probe ModuleImportExtensions<br/>(includes .txt, .md)
    Resolver-->>Loader: Return resolved path
    
    Loader->>Loader: Check IsTextAssetExtension()
    Loader->>ContentProvider: LoadContent(ResolvedPath)
    ContentProvider-->>Loader: Return UTF-8 string content
    
    Loader->>Loader: Build frozen metadata<br/>(kind, path, fileName,<br/>extension, byteLength)
    Loader->>Module: Create with exports:<br/>content, metadata
    Module-->>Loader: Return TGocciaModule
    Loader-->>Client: Return Module.Exports
    
    Client->>Module: Access content & metadata
    Module-->>Client: Return string & frozen object
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • PR #162: Directly modifies the same TGocciaModuleLoader and content-provider code paths with complementary structured-data and text-asset loading logic.
  • PR #151: Updates TGocciaModuleResolver with related import-map and extension-handling logic that interacts with this PR's resolver extension configuration.
  • PR #107: Earlier refactor of TGocciaModuleResolver extension-handling that this PR builds upon by replacing ScriptExtensions with the broader ModuleImportExtensions.

Poem

🐰 Hops through extensions new,
Text and markdown files too!
Frozen metadata, content so clear,
Asset imports now appear!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main feature added: support for importing .txt and .md text assets as modules.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch t3code/asset-text-imports

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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.

🧹 Nitpick comments (1)
tests/language/modules/text-import.js (1)

35-41: Namespace import test looks good, but key order assertion may be brittle.

The assertion expect(Object.keys(noteModule)).toEqual(["metadata", "content"]) assumes a specific enumeration order. If the module loader's export table preserves insertion order (as ES modules do), this is fine. However, if the order changes in the future (e.g., ["content", "metadata"]), this test would fail even though the functionality is correct.

Consider using a set-based comparison if order isn't semantically meaningful:

♻️ Optional: Order-agnostic assertion
-    expect(Object.keys(noteModule)).toEqual(["metadata", "content"]);
+    expect(Object.keys(noteModule).sort()).toEqual(["content", "metadata"]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/language/modules/text-import.js` around lines 35 - 41, The test
"supports namespace imports for text assets" is brittle because it asserts a
specific key order with Object.keys(noteModule) === ["metadata","content"];
change this to an order-agnostic check on noteModule's keys (e.g., compare as a
Set, or use arrayContaining plus a length check) so the test verifies both keys
exist and no extras without relying on enumeration order; update the assertion
that references noteModule accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/language/modules/text-import.js`:
- Around line 35-41: The test "supports namespace imports for text assets" is
brittle because it asserts a specific key order with Object.keys(noteModule) ===
["metadata","content"]; change this to an order-agnostic check on noteModule's
keys (e.g., compare as a Set, or use arrayContaining plus a length check) so the
test verifies both keys exist and no extras without relying on enumeration
order; update the assertion that references noteModule accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 93b99373-eb82-463b-9def-f6a9329dbe46

📥 Commits

Reviewing files that changed from the base of the PR and between 31f74d5 and 0ebe5ce.

📒 Files selected for processing (14)
  • AGENTS.md
  • README.md
  • docs/code-style.md
  • docs/design-decisions.md
  • docs/embedding.md
  • docs/language-restrictions.md
  • tests/language/modules/helpers/guide.md
  • tests/language/modules/helpers/note.txt
  • tests/language/modules/text-import.js
  • units/Goccia.Constants.PropertyNames.pas
  • units/Goccia.FileExtensions.pas
  • units/Goccia.Modules.ContentProvider.Test.pas
  • units/Goccia.Modules.Loader.pas
  • units/Goccia.Modules.Resolver.pas

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 6, 2026

Benchmark Results

274 benchmarks

Interpreted: 🟢 223 improved · 🔴 13 regressed · 38 unchanged · avg +5.5%
Bytecode: 🟢 155 improved · 🔴 39 regressed · 80 unchanged · avg +3.3%

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

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 6, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 3688 3688
Tests Passed 3647 ✅ 3688 ✅
Tests Skipped 41 0
Tests Execution 207.4ms 193.7ms
Tests Engine 384.0ms 678.5ms
Benchmarks Total 274 274
Benchmarks Duration 7.75min 6.81min

Measured on ubuntu-latest x64.

- Canonicalize CRLF and bare CR in `.txt`/`.md` module content
- Add regression coverage for imported text assets
- Update docs to describe the normalized `content` export
@frostney frostney merged commit d16da08 into main Apr 6, 2026
53 checks passed
@frostney frostney deleted the t3code/asset-text-imports branch April 6, 2026 21:37
@frostney frostney added the new feature New feature or request label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant