Skip to content

Add encodeURI / decodeURI / encodeURIComponent / decodeURIComponent#280

Merged
frostney merged 2 commits into
mainfrom
t3code/uri-encoding-builtins
Apr 12, 2026
Merged

Add encodeURI / decodeURI / encodeURIComponent / decodeURIComponent#280
frostney merged 2 commits into
mainfrom
t3code/uri-encoding-builtins

Conversation

@frostney
Copy link
Copy Markdown
Owner

Summary

  • Implements encodeURI, decodeURI, encodeURIComponent, and decodeURIComponent as global functions per ES2026 §19.2.6.
  • New shared Goccia.URI.pas unit with the Encode/Decode core algorithms, UTF-8 multi-byte support, surrogate validation, and overlong-encoding rejection. Also exposes PercentEncodePath for file-URL percent-encoding.
  • Unifies URI encoding: Goccia.ImportMeta.pas now uses the shared PercentEncodePath from Goccia.URI instead of its own private copy.
  • Adds ThrowURIError to Goccia.Values.ErrorHelper.pas (the URIError constructor and prototype already existed).
  • No Windows-specific edge cases for the URI functions themselves (pure string operations). The import.meta path-separator conversion (\/) remains unchanged and runs before the shared encoder.
  • Removes URI functions and atob/btoa from the "Deferred Built-ins" list in docs/language-restrictions.md.

Testing

  • Verified no regressions and confirmed the new feature or bugfix in end-to-end JavaScript/TypeScript tests
    • 56 new tests across 4 files (encodeURIComponent.js, decodeURIComponent.js, encodeURI.js, decodeURI.js), all passing in both interpreted and bytecode modes
    • Full suite: 4954 passed, 12 failed (all pre-existing FFI/ASI failures), 41 skipped — zero new regressions
    • import.meta tests (22/22) continue to pass after the PercentEncodePath unification
  • Updated documentation
    • CLAUDE.md: added Goccia.URI.pas to architecture table
    • docs/built-ins.md: documented all 4 functions with behavior details
    • docs/language-restrictions.md: removed from deferred list
  • 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

- Add `encodeURI`/`decodeURI` and `encodeURIComponent`/`decodeURIComponent`
- Share URI percent-encoding logic with `import.meta.url`
- Cover URI encoding behavior with built-in tests
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 12, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 15c0ef33-953b-4c13-a9b1-c23df9b6da7e

📥 Commits

Reviewing files that changed from the base of the PR and between b0bf73e and 37659f0.

📒 Files selected for processing (4)
  • tests/built-ins/decodeURI.js
  • tests/built-ins/encodeURI.js
  • tests/built-ins/encodeURIComponent.js
  • units/Goccia.URI.pas
✅ Files skipped from review due to trivial changes (1)
  • tests/built-ins/decodeURI.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/built-ins/encodeURIComponent.js
  • tests/built-ins/encodeURI.js
  • units/Goccia.URI.pas

📝 Walkthrough

Walkthrough

Adds ES2026 URI globals (encodeURI, decodeURI, encodeURIComponent, decodeURIComponent), a new shared URI unit (units/Goccia.URI.pas) with UTF‑8–aware percent-encoding/decoding and PercentEncodePath, integrates globals, updates ImportMeta to use the shared encoder, introduces ThrowURIError, adds comprehensive tests, and updates docs to reflect implementation (removed from unimplemented list).

Changes

Cohort / File(s) Summary
Core URI Implementation
units/Goccia.URI.pas
New unit implementing EncodeURI/EncodeURIComponent/DecodeURI/DecodeURIComponent and PercentEncodePath with UTF‑8-aware percent-encoding/decoding, strict hex validation, surrogate/overlong checks, and DecodeURI reserved-escape preservation.
Global Bindings
units/Goccia.Builtins.Globals.pas
Added native callbacks to expose the four URI functions as globals; coercion of missing arg to 'undefined'; added uses Goccia.URI.
ImportMeta Integration
units/Goccia.ImportMeta.pas
Removed local PercentEncodePath helper; added Goccia.URI to implementation uses so FilePathToUrl now delegates percent-encoding to the shared unit.
Error Helper
units/Goccia.Values.ErrorHelper.pas
Added ThrowURIError procedure that constructs and raises a URIError via CreateErrorObject.
Tests
tests/built-ins/encodeURI.js, tests/built-ins/encodeURIComponent.js, tests/built-ins/decodeURI.js, tests/built-ins/decodeURIComponent.js
Four new Jest suites covering availability, unreserved/reserved handling, UTF‑8 multi-byte cases, error cases (malformed escapes, invalid/truncated/overlong UTF‑8, lone surrogates), coercion, and round-trip properties.
Documentation & References
docs/built-ins.md, AGENTS.md, docs/language-restrictions.md
Docs updated to document the four URI globals, detail preserved vs. percent‑encoded characters, UTF‑8 semantics, URIError behaviors; removed URI/Base64 entries from unimplemented list; AGENTS updated to reference Goccia.URI.pas.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant JS as "JS caller"
participant Globals as "TGocciaGlobals (callbacks)"
participant URI as "Goccia.URI"
participant Err as "ErrorHelper (ThrowURIError)"
JS->>Globals: call encodeURI/encodeURIComponent/decodeURI/decodeURIComponent(arg)
Globals->>URI: Coerce arg to string; call Encode*/Decode*(string)
alt encoding/decoding succeeds
URI-->>Globals: return encoded/decoded string
Globals-->>JS: return string value
else validation error
URI->>Err: ThrowURIError("URI malformed")
Err-->>Globals: raises TGocciaThrowValue
Globals-->>JS: exception thrown
end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and concisely summarizes the main change: adding four URI encoding/decoding global functions.
Description check ✅ Passed The PR description covers the summary, testing (with checkboxes), documentation updates, and includes specific testing results. All required template sections are present and substantively completed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

@coderabbitai coderabbitai Bot added new feature New feature or request spec compliance Mismatch against official JavaScript/TypeScript specification labels Apr 12, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

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

Inline comments:
In `@tests/built-ins/encodeURI.js`:
- Around line 1-114: Add negative tests asserting that encodeURI throws a
URIError for unpaired (lone) surrogates: call encodeURI with a lone high
surrogate (e.g., "\uD800") and a lone low surrogate (e.g., "\uDC00") and assert
via expect(() => encodeURI(...)).toThrow(URIError); also include a small
positive control using a valid surrogate pair (e.g., "\uD83D\uDE00") to ensure
it does not throw. Locate tests around the existing encodeURI test suite and add
these cases referencing the encodeURI function.

In `@tests/built-ins/encodeURIComponent.js`:
- Around line 1-88: Add explicit tests that assert encodeURIComponent throws a
URIError for lone/mismatched UTF-16 surrogates: create a new test (e.g., "throws
URIError for lone surrogates") that calls encodeURIComponent with a lone high
surrogate ("\uD800"), a lone low surrogate ("\uDC00"), and a string with a
mismatched pair (e.g., "\uD800X" or "X\uDC00") and use expect(() =>
encodeURIComponent(...)).toThrow(URIError) for each case so the suite covers
this error condition alongside the existing multi-byte tests.

In `@units/Goccia.URI.pas`:
- Around line 297-308: The code incorrectly re-serializes reserved
percent-escapes using PercentEncodeByte (which uppercases hex) instead of
preserving the original three-character escape; in the Decode routine around the
DecodePercentByte call (see DecodePercentByte, PercentEncodeByte, AReservedSet
and the Buffer.Append call), capture the original percent-escape substring (the
three chars starting at current index before advancing/decoding), use
DecodePercentByte only to obtain B for character classification, but when
DecodedChar is in AReservedSet append the captured original substring verbatim
to Buffer instead of calling PercentEncodeByte, ensuring reserved escapes keep
their original hex case and form.
🪄 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: 281e93ea-0fa8-4bcc-8634-754d23b98f22

📥 Commits

Reviewing files that changed from the base of the PR and between dfb9ffe and b0bf73e.

📒 Files selected for processing (11)
  • AGENTS.md
  • docs/built-ins.md
  • docs/language-restrictions.md
  • tests/built-ins/decodeURI.js
  • tests/built-ins/decodeURIComponent.js
  • tests/built-ins/encodeURI.js
  • tests/built-ins/encodeURIComponent.js
  • units/Goccia.Builtins.Globals.pas
  • units/Goccia.ImportMeta.pas
  • units/Goccia.URI.pas
  • units/Goccia.Values.ErrorHelper.pas
💤 Files with no reviewable changes (1)
  • docs/language-restrictions.md

Comment thread tests/built-ins/encodeURI.js
Comment thread tests/built-ins/encodeURIComponent.js
Comment thread units/Goccia.URI.pas
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 12, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 5073 5073
Tests Passed 5032 ✅ 5073 ✅
Tests Skipped 41 0
Tests Test Duration 356.8ms 339.6ms
Tests Lex 96.3ms 66.1ms
Tests Parse 123.0ms 124.9ms
Tests Compile 79.3ms
Tests Execute 373.9ms 371.4ms
Tests Engine Total 593.3ms 641.8ms
Benchmarks Total 364 364
Benchmarks Duration 9.71min 8.75min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 12, 2026

Benchmark Results

364 benchmarks

Interpreted: 🟢 99 improved · 🔴 110 regressed · 155 unchanged · avg -0.1%
Bytecode: 🟢 300 improved · 🔴 24 regressed · 40 unchanged · avg +7.2%

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

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

- Decode now captures the original %XX substring and re-emits it
  verbatim for reserved characters instead of normalizing hex case
  via PercentEncodeByte (ES2026 §19.2.6.2 step 4b.ii.1).
- Add lone surrogate URIError tests to encodeURI and
  encodeURIComponent test suites.
- Fix decodeURI test that incorrectly expected case normalization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@frostney frostney merged commit 130c3dc into main Apr 12, 2026
9 checks passed
@frostney frostney deleted the t3code/uri-encoding-builtins branch April 12, 2026 13:39
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 spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant