Skip to content

Fix Number toString scientific notation threshold and format#415

Merged
frostney merged 3 commits into
mainfrom
t3code/verify-implement-400
Apr 27, 2026
Merged

Fix Number toString scientific notation threshold and format#415
frostney merged 3 commits into
mainfrom
t3code/verify-implement-400

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Apr 27, 2026

Summary

Fixes #400.

  • Implement DoubleToESString per ES2026 §6.1.6.1.13 — integers in [1e15, 1e21) now use fixed-point notation instead of premature scientific notation, and scientific notation uses lowercase e+/e- per spec
  • Replace FloatToStr in ToStringLiteral and the parser's numeric property key paths, fixing String(n), template literals, JSON.stringify, and computed member names for large integers
  • Add 10 new test cases covering the issue's repro, Number.MAX_SAFE_INTEGER, negative large integers, 5e-324, small-number thresholds, and implicit coercion paths

- Use ES-style decimal/scientific formatting for numeric literals and values
- Add coverage for large integers, small magnitudes, and string coercion
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 27, 2026

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

Project Deployment Actions Updated (UTC)
gocciascript-homepage Ready Ready Preview, Comment Apr 27, 2026 11:24am

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6c9fa081-319f-4906-abdf-f9acbe371794

📥 Commits

Reviewing files that changed from the base of the PR and between 6b0c4bb and f455060.

📒 Files selected for processing (1)
  • source/units/Goccia.Values.Primitives.pas

📝 Walkthrough

Walkthrough

Replaces ad-hoc FloatToStr formatting with a new ES2026-aligned DoubleToESString for number-to-string paths and updates parser and JSON serialization to use it; expands Number.prototype.toString tests to cover fixed-point vs scientific thresholds and coercion equivalence.

Changes

Cohort / File(s) Summary
Number formatting core
source/units/Goccia.Values.Primitives.pas
Adds DoubleToESString(AValue: Double): string and replaces finite non-zero FloatToStr usage with ES2026-style formatting including safe-integer fast path and shortest round-trip decimal/scientific output.
Parser usage
source/units/Goccia.Parser.pas
Replaces numeric-derived identifier/key stringification from FloatToStr to DoubleToESString.
JSON serialization
source/units/Goccia.JSON.pas
Replaces prior round-trip/normalization logic with a direct call to DoubleToESString for finite JSON numbers, removing the old helpers and constants.
Tests
tests/built-ins/Number/prototype/toString.js
Adds assertions verifying fixed-point formatting for integers < 1e21, scientific notation for ≥ 1e21 and extreme magnitudes, and coercion equivalence (String(...), template literals, concatenation).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately captures the main change: fixing Number toString's scientific notation threshold and format behavior for large integers to comply with ES2026.
Description check ✅ Passed The description includes a summary with linked issue reference (#400), implementation details, and testing coverage notes, largely matching the template structure.
Linked Issues check ✅ Passed The PR implements DoubleToESString to fix scientific notation thresholds and format [1e15, 1e21) as fixed-point instead of scientific, lowercase e+/e- per spec, and updates all affected paths.
Out of Scope Changes check ✅ Passed All changes (DoubleToESString function, replacements in Goccia.Parser.pas and Goccia.JSON.pas, and new tests) are directly tied to fixing issue #400 with no extraneous modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

@coderabbitai coderabbitai Bot added bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification labels Apr 27, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
source/units/Goccia.Values.Primitives.pas (1)

161-162: Use the exact spec pseudo-signature in the annotation.

These comments are close, but the repo convention is the exact SpecMethodName(specParams) form immediately above the implementation. Using the canonical signature here will keep spec-audit grepability consistent.

As per coding guidelines, annotate each function implementing ECMAScript-specified behavior with // ESYYYY §X.Y.Z SpecMethodName(specParams) immediately above the function body, using the spec's pseudo-code method name and parameters exactly as written.

Also applies to: 184-194

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@source/units/Goccia.Values.Primitives.pas` around lines 161 - 162, The
comment above DoubleToESString uses a descriptive note instead of the required
canonical spec pseudo-signature; replace it with an exact spec annotation in the
repo convention format (for example: // ES2026 §6.1.6.1.13 Number::toString(x) )
placed immediately above the function body, and do the same for the other
ECMAScript-implementing routines in the same area (the functions around the
later numeric/string helper implementations referenced in your review) so each
has the exact SpecMethodName(specParams) and section number as the single-line
comment immediately above its implementation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@source/units/Goccia.Values.Primitives.pas`:
- Around line 194-317: Replace the JSON path that formats finite doubles with
your new ES formatter: find the code that calls FloatToStr(...) for serializing
numbers (the JSON stringify/serialize routine that handles finite numbers,
referenced around the FloatToStr use in Goccia.JSON) and call
DoubleToESString(AValue) instead; also add the unit that exposes
DoubleToESString to the uses clause if it isn't already referenced. Do the same
replacement at the other occurrence noted (the second FloatToStr site) so all
finite-number JSON serialization uses DoubleToESString and preserves existing
sign/NaN/Infinity handling.

---

Nitpick comments:
In `@source/units/Goccia.Values.Primitives.pas`:
- Around line 161-162: The comment above DoubleToESString uses a descriptive
note instead of the required canonical spec pseudo-signature; replace it with an
exact spec annotation in the repo convention format (for example: // ES2026
§6.1.6.1.13 Number::toString(x) ) placed immediately above the function body,
and do the same for the other ECMAScript-implementing routines in the same area
(the functions around the later numeric/string helper implementations referenced
in your review) so each has the exact SpecMethodName(specParams) and section
number as the single-line comment immediately above its implementation.
🪄 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: e32f34e9-9d34-4482-91c3-8f2a9488cf8b

📥 Commits

Reviewing files that changed from the base of the PR and between fbd1116 and cf836e8.

📒 Files selected for processing (3)
  • source/units/Goccia.Parser.pas
  • source/units/Goccia.Values.Primitives.pas
  • tests/built-ins/Number/prototype/toString.js

Comment thread source/units/Goccia.Values.Primitives.pas
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 7883 7883
Tests Passed 7842 ✅ 7883 ✅
Tests Skipped 41 0
Tests Workers 4 4
Tests Test Duration 1.30s 1.91s
Tests Lex (cumulative) 143.3ms 128.4ms
Tests Parse (cumulative) 216.1ms 313.0ms
Tests Compile (cumulative) 204.8ms
Tests Execute (cumulative) 1.12s 1.57s
Tests Engine Total (cumulative) 1.48s 2.22s
Tests Lex (avg/worker) 35.8ms 32.1ms
Tests Parse (avg/worker) 54.0ms 78.2ms
Tests Compile (avg/worker) 51.2ms
Tests Execute (avg/worker) 279.0ms 393.5ms
Tests Engine Total (avg/worker) 368.9ms 555.0ms
Benchmarks Total 386 386
Benchmarks Workers 4 4
Benchmarks Duration 2.89min 2.99min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 27, 2026

Benchmark Results

386 benchmarks

Interpreted: 🟢 30 improved · 🔴 122 regressed · 234 unchanged · avg -1.8%
Bytecode: 🟢 323 improved · 🔴 11 regressed · 52 unchanged · avg +9.4%

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

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.

SerializeJSONNumber now delegates to DoubleToESString (ES2026
§25.5.2.5 step 8.a calls ToString), removing the separate
FloatToStr + NormalizeExponentNumber pipeline and its dead helpers.
Spec annotation comments updated to the canonical format.

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

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@source/units/Goccia.Values.Primitives.pas`:
- Around line 242-305: The DoubleToESString routine uses DefaultFormatSettings
(FS) but doesn't enforce an invariant decimal separator, so locale settings can
break parsing; fix by setting FS.DecimalSeparator := '.' immediately after FS :=
DefaultFormatSettings in DoubleToESString so that subsequent calls to Str(...,
SciStr), TryStrToFloat(..., FS) and FloatToStr(..., FS) always use '.' as the
decimal separator.
🪄 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: fac8b107-222c-4055-bd6c-d7e2d2b2e07d

📥 Commits

Reviewing files that changed from the base of the PR and between cf836e8 and 6b0c4bb.

📒 Files selected for processing (2)
  • source/units/Goccia.JSON.pas
  • source/units/Goccia.Values.Primitives.pas

Comment thread source/units/Goccia.Values.Primitives.pas
FPC 3.2.2 aliases DefaultFormatSettings and FormatSettings via
Absolute, so a locale with ',' as decimal separator would break the
Str/TryStrToFloat round-trip. Pin FS.DecimalSeparator := '.' to
match every other format-settings site in the codebase.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@frostney frostney merged commit 56c22b8 into main Apr 27, 2026
58 checks passed
@frostney frostney deleted the t3code/verify-implement-400 branch April 27, 2026 11:51
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.

Number ToString uses scientific notation prematurely for integers >= 1e15

1 participant