Skip to content

Fix NumberFormat digit option resolution#679

Merged
frostney merged 3 commits into
mainfrom
t3code/issue-643-fix
May 22, 2026
Merged

Fix NumberFormat digit option resolution#679
frostney merged 3 commits into
mainfrom
t3code/issue-643-fix

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented May 20, 2026

Summary

  • Fix Intl.NumberFormat digit option resolution for one-sided currency fraction bounds so missing bounds use currency-specific defaults.
  • Resolve both fraction and significant digit families for non-auto roundingPriority.
  • Route format(), formatToParts(), formatRange(), and formatRangeToParts() through ICU NumberFormatter skeletons so ICU owns rounding modes, rounding increments, sign display, and mixed fraction/significant precision consistently.
  • Add focused resolvedOptions(), format(), and formatRange() regressions, including mixed roundingPriority, negative zero sign display, significant digits, and large roundingIncrement coverage.
  • Closes Implement full ECMA-402 SetNumberFormatDigitOptions for one-sided and mixed digit bounds #643.

Testing

  • Verified no regressions and confirmed the new feature or bugfix in end-to-end JavaScript/TypeScript tests
  • Updated documentation (not needed; behavior fix covered by tests)
  • 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

Additional verification run locally:

  • ./format.pas --check
  • ./build.pas testrunner loaderbare
  • ./build/GocciaTestRunner tests/built-ins/Intl/NumberFormat --asi --unsafe-ffi --no-progress
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/prototype/format/format-rounding-mode-*.js' --output /tmp/goccia-test262-rounding-mode.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/prototype/format/format-fraction-digits-precision.js' --output /tmp/goccia-test262-fraction-digits-precision.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/prototype/format/format-significant-digits.js' --output /tmp/goccia-test262-significant-digits.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/prototype/format/format-rounding-priority-*' --output /tmp/goccia-test262-rounding-priority.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/test-option-roundingPriority-mixed-options.js' --output /tmp/goccia-test262-rounding-priority-mixed.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/prototype/format/format-rounding-increment-*' --output /tmp/goccia-test262-rounding-increment.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/prototype/format/signDisplay-rounding.js' --output /tmp/goccia-test262-sign-display-rounding.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/prototype/formatRange/*.js' --output /tmp/goccia-test262-format-range-only.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/prototype/formatRangeToParts/*.js' --output /tmp/goccia-test262-format-range-parts.json --jobs=2
  • bun scripts/run_test262_suite.ts --suite-dir /tmp/goccia-test262-d0c1b4555b03dd404873fd6422a4b5da00136500 --filter 'intl402/NumberFormat/**/*.js' --output /tmp/goccia-test262-numberformat-all.json --jobs=2 (subtree has expected pre-existing failures; the rounding regression files above pass)
  • ./build/GocciaTestRunner tests --asi --unsafe-ffi --no-progress

@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Preview May 22, 2026 6:59am

Request Review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces rounding priority support and migrates number formatting to use ICU's skeleton-based unumf_* APIs. It adds the TIntlNumberRoundingPriority enum, integrates new unumf function pointers, refactors precision skeleton builders to handle rounding increment and priority, implements skeleton-based number formatting routing with fallback to legacy methods, updates constructor validation for digit bounds and rounding constraints, and includes comprehensive conformance tests.

Changes

Rounding Priority & Skeleton-Based Number Formatting

Layer / File(s) Summary
Rounding priority type contracts
source/shared/IntlTypes.pas
TIntlNumberRoundingPriority enum (inrpAuto, inrpMorePrecision, inrpLessPrecision) is introduced and added to TIntlNumberFormatOptions; default options initialize rounding priority to inrpAuto.
ICU unumf function pointer integration
source/shared/IntlICU.pas
Math unit is added, unumf dynamic function-pointer types are defined for skeleton-based formatting, TIntlICUFunctions record is extended with unumf entry points, and TryLoadIntlFunctions resolves and loads the new function pointers.
Skeleton builders with rounding priority support
source/shared/IntlICU.pas
BuildFractionPrecisionStem helper extracts fractional precision logic; RoundingIncrementSkeletonDecimal constant is added; BuildPrecisionSkeleton unifies precision skeleton construction to handle rounding increment, priority, and significant/fraction digit combinations; rounding-mode tokens (half-ceiling/half-floor/half-up/half-down/half-even) are added; CanUseLegacyNumberFormatter and TryICUFormatNumberSkeleton routing helpers are introduced.
Skeleton-based number formatting routing
source/shared/IntlICU.pas
TryICUFormatNumber attempts skeleton-based unumf formatting before falling back to legacy; TryICUFormatNumberToPartsSkeleton implements skeleton-based "to parts" output via unumf result-as-value conversion; TryICUFormatNumberToParts prefers skeleton-based parts formatting; prior ApplyRoundingIncrement adjustment is removed from number-range start/end processing.
Constructor digit bounds and rounding priority validation
source/units/Goccia.Values.IntlNumberFormat.pas
CompactDisplayStringToEnum and RoundingPriorityStringToEnum convert option strings to enums; local variables track currency digit defaults and digit-requirement flags; digit-bounds computation is reworked to account for roundingPriority, notation, existing min/max settings, and roundingIncrement; special override applies when neither significant nor fraction digits are required; numberingSystem defaults to "latn"; roundingIncrement constraints are validated against digit-rounding mode and significant-digit state; resolved CompactDisplay and RoundingPriority are populated from stored strings.
Conformance tests for rounding priority and formatting
tests/built-ins/Intl/NumberFormat/prototype/format.js, tests/built-ins/Intl/NumberFormat/prototype/formatRange.js, tests/built-ins/Intl/NumberFormat/prototype/resolvedOptions.js
Tests added for negative-zero preservation (including signDisplay: "exceptZero"), significant-digit formatting with exact decimal precision, roundingPriority differences ("morePrecision" vs "lessPrecision"), roundingIncrement alignment to fraction-digit grid, notation modes (scientific/engineering/compact with compactDisplay: "long"), formatRange with rounding priority, currency-style resolvedOptions with one-sided fraction defaults from currency digits, and invalid roundingPriority validation raising RangeError.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related issues

  • #643: Implements full ECMA-402 SetNumberFormatDigitOptions for one-sided and mixed digit bounds—this PR directly addresses the digit-bounds validation and mixed roundingPriority handling gaps described in the issue by reworking constructor digit computation and enabling both significant and fraction digit families to coexist with proper rounding selection at format time.
  • #635: The main changes directly implement roundingPriority support and refactor how roundingIncrement is handled in source/shared/IntlICU.pas (including removing prior ApplyRoundingIncrement usage and adding skeleton-based precision/rounding logic), so this fixes the same ApplyRoundingIncrement precision and roundingPriority gaps described in the retrieved issue.

Possibly related PRs

  • frostney/GocciaScript#631: Both PRs modify source/shared/IntlICU.pas's number-formatting pipeline—especially TryICUFormatNumber—to incorporate ICU rounding options (roundingIncrement/rounding-mode/priorities), so the main PR's skeleton/unumf changes build on the same ICU rounding/formatting integration points.
  • frostney/GocciaScript#658: Both PRs modify source/shared/IntlICU.pas's number-range implementation—main PR changes the rounding-increment/precision skeleton construction path used before range skeleton formatting, while retrieved PR adds ICU skeleton-based formatRange/formatRangeToParts APIs and range skeleton plumbing—so the changes are directly connected at the range-skeleton/range-formatting code level.

Suggested labels

bug, spec compliance

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix NumberFormat digit option resolution' accurately describes the primary change—fixing digit option resolution in NumberFormat per ECMA-402 requirements.
Description check ✅ Passed The description is comprehensive, covering the summary, testing checklist, and detailed verification steps; it follows the template structure and provides clear context for the changes.
Linked Issues check ✅ Passed The code changes fully address issue #643: one-sided currency fraction bounds now use currency defaults [#643], both digit families are resolved for non-auto roundingPriority [#643], and skeleton-based formatting enables consistent rounding behavior [#643].
Out of Scope Changes check ✅ Passed All changes are scoped to issue #643: IntlICU.pas and IntlTypes.pas implement rounding/skeleton logic, Goccia.Values.IntlNumberFormat.pas implements digit resolution, and test files add regressions; no unrelated changes detected.
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.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

Suite Timing

Test Runner (interpreted: 9,788 passed; bytecode: 9,788 passed)
Metric Interpreted Bytecode
Total 9788 9788
Passed 9788 ✅ 9788 ✅
Workers 4 4
Test Duration 2.21s 3.11s
Lex (cumulative) 320.5ms 330.8ms
Parse (cumulative) 212.4ms 282.7ms
Compile (cumulative) 654.0ms
Execute (cumulative) 1.98s 2.98s
Engine Total (cumulative) 2.52s 4.25s
Lex (avg/worker) 80.1ms 82.7ms
Parse (avg/worker) 53.1ms 70.7ms
Compile (avg/worker) 163.5ms
Execute (avg/worker) 496.0ms 744.9ms
Engine Total (avg/worker) 629.3ms 1.06s

Memory

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

Metric Interpreted Bytecode
GC Live 280.39 MiB 274.65 MiB
GC Peak Live 280.40 MiB 274.66 MiB
GC Allocated During Run 284.87 MiB 279.13 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 1 1
GC Collected Objects 88 88
Heap Start Allocated 158.8 KiB 158.8 KiB
Heap End Allocated 1.53 MiB 1.53 MiB
Heap Delta Allocated 1.37 MiB 1.37 MiB
Heap Delta Free 449.1 KiB 449.1 KiB
Benchmarks (interpreted: 407; bytecode: 407)
Metric Interpreted Bytecode
Total 407 407
Workers 4 4
Duration 2.50min 2.37min

Memory

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

Metric Interpreted Bytecode
GC Live 3.93 MiB 3.93 MiB
GC Peak Live 104.77 MiB 74.76 MiB
GC Allocated During Run 15.29 GiB 10.28 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 2,817 2,671
GC Collected Objects 277,387,266 236,762,167
Heap Start Allocated 1.27 MiB 1.27 MiB
Heap End Allocated 1.27 MiB 1.27 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

Benchmark Results

407 benchmarks

Interpreted: 🟢 191 improved · 🔴 41 regressed · 175 unchanged · avg +5.2%
Bytecode: 🟢 319 improved · 🔴 25 regressed · 63 unchanged · avg +7.4%

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

Deterministic profile diff

Deterministic profile diff: no significant changes.

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 20, 2026

test262 Conformance

Category Run Passed Δ Pass Failed Pass-rate Δ Rate
built-ins 23,449 16,067 +1 7,377 68.5% ±0pp
harness 116 72 ±0 44 62.1% ±0pp
intl402 3,324 920 +28 2,404 27.7% +0.8pp
language 23,635 14,433 ±0 9,202 61.1% ±0pp
staging 1,484 571 ±0 910 38.5% ±0pp
total 52,008 32,063 +29 19,937 61.7% +0.1pp

Areas closest to 100%

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

Newly passing (29):

  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js
  • intl402/NumberFormat/currency-digits-nonstandard-notation.js
  • intl402/NumberFormat/prototype/format/format-rounding-priority-less-precision.js
  • intl402/NumberFormat/prototype/format/format-rounding-priority-more-precision.js
  • intl402/NumberFormat/prototype/format/signDisplay-currency-de-DE.js
  • intl402/NumberFormat/prototype/format/signDisplay-negative-currency-de-DE.js
  • intl402/NumberFormat/prototype/format/signDisplay-negative-de-DE.js
  • intl402/NumberFormat/prototype/format/signDisplay-negative-en-US.js
  • intl402/NumberFormat/prototype/format/signDisplay-negative-ja-JP.js
  • intl402/NumberFormat/prototype/format/signDisplay-negative-ko-KR.js
  • intl402/NumberFormat/prototype/format/signDisplay-negative-zh-TW.js
  • intl402/NumberFormat/prototype/format/signDisplay-rounding.js
  • intl402/NumberFormat/prototype/format/unit-de-DE.js
  • intl402/NumberFormat/prototype/format/unit-en-US.js
  • intl402/NumberFormat/prototype/format/unit-ja-JP.js
  • intl402/NumberFormat/prototype/format/unit-ko-KR.js
  • intl402/NumberFormat/prototype/format/unit-zh-TW.js
  • intl402/NumberFormat/prototype/format/useGrouping-extended-de-DE.js
  • intl402/NumberFormat/prototype/format/useGrouping-extended-en-US.js
  • intl402/NumberFormat/prototype/formatToParts/signDisplay-currency-de-DE.js
  • intl402/NumberFormat/prototype/formatToParts/signDisplay-negative-currency-de-DE.js
  • intl402/NumberFormat/prototype/formatToParts/unit-de-DE.js
  • intl402/NumberFormat/prototype/formatToParts/unit-en-US.js
  • intl402/NumberFormat/prototype/formatToParts/unit-ja-JP.js
  • intl402/NumberFormat/prototype/formatToParts/unit-ko-KR.js
  • intl402/NumberFormat/prototype/formatToParts/unit-zh-TW.js
  • intl402/NumberFormat/prototype/formatToParts/unit.js
  • intl402/NumberFormat/test-option-roundingPriority-mixed-options.js
  • intl402/NumberFormat/test-option-roundingPriority.js

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

@frostney frostney force-pushed the t3code/issue-643-fix branch 2 times, most recently from 23ba436 to 26347d7 Compare May 21, 2026 08:36
@frostney frostney force-pushed the t3code/issue-643-fix branch from 26347d7 to 26ba078 Compare May 21, 2026 13:38
@frostney frostney marked this pull request as ready for review May 22, 2026 06:41
@coderabbitai coderabbitai Bot added bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification labels May 22, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
source/shared/IntlICU.pas (1)

78-78: 💤 Low value

Potentially unused Math unit import

source/shared/IntlICU.pas has Math in its uses clause, but there are no Math.-qualified calls and no usage of Math-specific functions like Max, Min, Power, Floor, Ceil, etc. The only matches are System.Round and unqualified Abs/Trunc, which can come from System. Remove Math if those are the only needs.

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

In `@source/shared/IntlICU.pas` at line 78, The uses clause currently includes the
Math unit but the file (IntlICU.pas) does not call any Math-qualified
identifiers; remove "Math" from the uses clause in the unit declaration to avoid
an unused import, then compile to confirm no missing references; if any Math
functions (e.g., Max, Min, Power, Floor, Ceil) are actually used unqualified,
either qualify them with System. or re-add/import only the needed functions
instead of the whole Math unit; ensure symbols like Round, Abs, Trunc referenced
in the file resolve from System or other units after the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@source/units/Goccia.Values.IntlNumberFormat.pas`:
- Around line 148-154: The new Pascal identifiers violate the repo naming rule
by using PascalCase; rename functions CompactDisplayStringToEnum and
RoundingPriorityStringToEnum and variables CurrDigits, MinimumFractionDefault
(and the other identifiers referenced at lines ~200-208 and ~513-516) to
camelCase (e.g., compactDisplayStringToEnum, roundingPriorityStringToEnum,
currDigits, minimumFractionDefault), update their declarations and all
call-sites/usages in this unit to the new names, and run a quick compile to
catch any missed references.
- Around line 587-601: The current gating on FNotation prevents currency digit
defaults from being applied for non-standard notations; update the branch around
the FStyle = 'currency' check so that when FStyle = 'currency' you always call
TryGetCurrencyInfo(FLocale, FCurrency, CurrSymbol, CurrNarrow, CurrDigits)
(falling back to CurrDigits := 2 on failure) and assign MinimumFractionDefault
:= CurrDigits and MaximumFractionDefault := CurrDigits regardless of FNotation,
then let any later compact/scientific/engineering-specific overrides apply;
modify the code paths that currently set
MinimumFractionDefault/MaximumFractionDefault based on FNotation so they no
longer bypass the currency-derived defaults for FCurrency.

---

Nitpick comments:
In `@source/shared/IntlICU.pas`:
- Line 78: The uses clause currently includes the Math unit but the file
(IntlICU.pas) does not call any Math-qualified identifiers; remove "Math" from
the uses clause in the unit declaration to avoid an unused import, then compile
to confirm no missing references; if any Math functions (e.g., Max, Min, Power,
Floor, Ceil) are actually used unqualified, either qualify them with System. or
re-add/import only the needed functions instead of the whole Math unit; ensure
symbols like Round, Abs, Trunc referenced in the file resolve from System or
other units after the change.
🪄 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: 4a2d441a-a15f-40ea-a5af-d071dcc26b0a

📥 Commits

Reviewing files that changed from the base of the PR and between 4cebde7 and 333720d.

📒 Files selected for processing (6)
  • source/shared/IntlICU.pas
  • source/shared/IntlTypes.pas
  • source/units/Goccia.Values.IntlNumberFormat.pas
  • tests/built-ins/Intl/NumberFormat/prototype/format.js
  • tests/built-ins/Intl/NumberFormat/prototype/formatRange.js
  • tests/built-ins/Intl/NumberFormat/prototype/resolvedOptions.js

Comment thread source/units/Goccia.Values.IntlNumberFormat.pas
Comment thread source/units/Goccia.Values.IntlNumberFormat.pas
@frostney frostney merged commit 52d8cc3 into main May 22, 2026
14 checks passed
@frostney frostney deleted the t3code/issue-643-fix branch May 22, 2026 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement full ECMA-402 SetNumberFormatDigitOptions for one-sided and mixed digit bounds

1 participant