Skip to content

fix(engine): deduplicate string-to-number across runtime and compiler#792

Merged
frostney merged 2 commits into
mainfrom
claude/compassionate-rhodes-424905
Jun 24, 2026
Merged

fix(engine): deduplicate string-to-number across runtime and compiler#792
frostney merged 2 commits into
mainfrom
claude/compassionate-rhodes-424905

Conversation

@frostney

Copy link
Copy Markdown
Owner

Summary

  • ECMA-262 StringToNumber (§7.1.4.1.1) was implemented twice — runtime coercion in TGocciaStringLiteralValue.ToNumberLiteral (Goccia.Values.Primitives) and compile-time folding in StringToCompileTimeNumber (Goccia.Compiler.ConstantValue) — so the interpreter and the bytecode constant optimizer could fold the same string source to different values (the +Infinity regression class).
  • Centralizes the logic in a new side-effect-free source/shared/NumericText.pasStringToNumber(const AText: string): Double, used by both paths. It returns a raw Double, so the compiler reuses it without instantiating a JS value (per the issue's allocation requirement). Net −171/+10 across the two units.
  • Scope note / divergence from the original issue text: the issue is framed as a pure dedup, but its Expected behavior lists hex/binary/octal prefixes, signed Infinity, invalid→NaN, and signed-zero as cases that must agree. Those were latently broken identically in both paths, so (confirmed during planning) implementing the StringNumericLiteral grammar once makes them correct rather than consistently wrong. Now fixed and verified identical in both execution modes:
    • +"0b101"5, +"0o17"15 (binary/octal were NaN)
    • +"0xABCDEF12345"11806310474565 (was a 32-bit-wrapped -554622139 via StrToInt)
    • +"Inf"NaN, +"."NaN (were Infinity/0)
    • +"+0x10"/+"-0x10"NaN (no sign on non-decimal); whitespace trimming and -0 preserved
  • Constraints / non-goals: no bytecode format or opcode change — the ADR 0040 compiler-optimizer design is unchanged; JSON/JSON5/TOML data-format parsers are out of scope.
  • New ADR 0070 — Shared string-to-number conversion records the centralization and the new-shared-unit home decision.

Closes #787

Testing

  • Verified no regressions and confirmed the bugfix in end-to-end JavaScript/TypeScript tests — full suite 10821/10821 pass in both interpreter and --mode=bytecode; new tests/language/expressions/string-to-number/string-numeric-literal.js exercises the full matrix and asserts both the constant-folded (+"literal") and runtime (Number(s)) paths.
  • Updated documentation — ADR 0070 added + indexed; no language.md/built-ins.md change (internal helper + conformance fix, no new public API surface).
  • Optional: native Pascal tests — value types (Primitives) changed; added co-located source/shared/NumericText.Test.pas (7/7, incl. bit-level -0/NaN/large-hex); full ./build.pas tests clean-builds green.
  • Optional: benchmarks — not applicable (no hot-path or allocation regression; runtime now allocates a fresh number per string coercion as the decimal path already did).

frostney and others added 2 commits June 24, 2026 19:05
Runtime coercion (TGocciaStringLiteralValue.ToNumberLiteral) and bytecode
constant folding (StringToCompileTimeNumber) each kept a partial copy of the
ECMA-262 StringToNumber parser, so the interpreter and the constant optimizer
could fold the same string source to different values.

Centralize the logic in a new side-effect-free source/shared/NumericText.pas
StringToNumber(): Double, used by both paths (the compiler reuses it without
allocating a value object). Implementing the StringNumericLiteral grammar once
also closes the shared conformance gaps the two copies had: binary/octal
literals (0b/0o), full-magnitude hex (no 32-bit wrap), rejection of "Inf" and
bare punctuation, and sign rejection on non-decimal literals; whitespace
trimming and signed zero are preserved.

No bytecode format or opcode change (ADR 0040 optimizer design unchanged).

Closes #787

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gocciascript-homepage Ignored Ignored Jun 24, 2026 6:07pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

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: 2d6ac66d-4aff-4786-b6a5-a3b5f4b2996a

📥 Commits

Reviewing files that changed from the base of the PR and between 5319ade and 255a63b.

📒 Files selected for processing (7)
  • docs/adr/0070-shared-string-to-number.md
  • docs/adr/README.md
  • source/shared/NumericText.Test.pas
  • source/shared/NumericText.pas
  • source/units/Goccia.Compiler.ConstantValue.pas
  • source/units/Goccia.Values.Primitives.pas
  • tests/language/expressions/string-to-number/string-numeric-literal.js

📝 Walkthrough

Walkthrough

A new NumericText unit is introduced with a single StringToNumber(const AText: string): Double function implementing ECMAScript StringNumericLiteral semantics. Both the runtime string-to-number coercion (TGocciaStringLiteralValue.ToNumberLiteral) and the compiler constant-folding path (TryCompileTimeValueToNumber) are rewired to delegate to this shared helper, removing their respective inline implementations. Unit tests in Pascal and a JS integration test suite covering both execution paths are added, along with ADR 0070.

Changes

Shared StringToNumber consolidation

Layer / File(s) Summary
NumericText unit — public API, non-decimal and decimal parsing, main entry point
source/shared/NumericText.pas
Declares StringToNumber in the interface. Implements HexDigitValue and TryNonDecimalIntegerToNumber for 0b/0o/0x inputs. Adds IsStrDecimalLiteral grammar validation and StrDecimalLiteralToNumber conversion. Exports StringToNumber which trims ECMAScript whitespace then dispatches to empty-string, Infinity, non-decimal, decimal, or NaN paths.
Runtime and compiler callers rewired to NumericText
source/units/Goccia.Values.Primitives.pas, source/units/Goccia.Compiler.ConstantValue.pas
TGocciaStringLiteralValue.ToNumberLiteral is replaced by StringToNumber(FValue) wrapped in TGocciaNumberLiteralValue.Create; all prior bespoke parsing logic is deleted. StringToCompileTimeNumber is removed from Goccia.Compiler.ConstantValue and TryCompileTimeValueToNumber's ctvkString branch calls StringToNumber directly. Both uses clauses are updated to reference NumericText.
Unit tests, integration tests, and ADR
source/shared/NumericText.Test.pas, tests/language/expressions/string-to-number/string-numeric-literal.js, docs/adr/0070-shared-string-to-number.md, docs/adr/README.md
NumericText.Test.pas adds TNumericTextTests with IEEE bit-based zero helpers and cases for whitespace, Infinity/NaN, non-decimal, decimal, signed zero, and invalid inputs. string-numeric-literal.js exercises both constant-folding and runtime coercion across the same categories using a dyn helper. ADR 0070 documents the shared helper decision and is indexed in README.md.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

bug, spec compliance

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: deduplicating string-to-number conversion across runtime and compiler.
Description check ✅ Passed The description matches the template with Summary and Testing sections, includes constraints, related issue, and test notes.
Linked Issues check ✅ Passed The PR implements a shared side-effect-free helper, unifies runtime and compile-time paths, adds tests, and avoids bytecode/opcode changes.
Out of Scope Changes check ✅ Passed The changes stay within the stated scope: shared numeric conversion, related tests, and ADR/docs updates only.
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.

@github-actions

Copy link
Copy Markdown
Contributor

Suite Timing

Test Runner (interpreted: 10,821 passed; bytecode: 10,821 passed)
Metric Interpreted Bytecode
Total 10821 10821
Passed 10821 ✅ 10821 ✅
Workers 4 4
Test Duration 17.13s 17.44s
Lex (cumulative) 559.4ms 555.8ms
Parse (cumulative) 386.9ms 391.0ms
Compile (cumulative) 785.9ms
Execute (cumulative) 106.3ms 37.59s
Engine Total (cumulative) 1.05s 39.32s
Lex (avg/worker) 139.8ms 139.0ms
Parse (avg/worker) 96.7ms 97.8ms
Compile (avg/worker) 196.5ms
Execute (avg/worker) 26.6ms 9.40s
Engine Total (avg/worker) 263.1ms 9.83s

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 271.71 MiB 269.47 MiB
GC Peak Live 283.80 MiB 310.93 MiB
GC Allocated During Run 433.98 MiB 425.69 MiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 188 188
GC Collected Objects 1,283,191 1,254,807
Heap Start Allocated 179.2 KiB 179.2 KiB
Heap End Allocated 3.65 MiB 3.65 MiB
Heap Delta Allocated 3.47 MiB 3.47 MiB
Heap Delta Free 1.65 MiB 1.65 MiB
Benchmarks (interpreted: 430; bytecode: 430)
Metric Interpreted Bytecode
Total 430 430
Workers 4 4
Duration 2.85min 2.72min

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 6.08 MiB 6.08 MiB
GC Peak Live 95.16 MiB 78.57 MiB
GC Allocated During Run 13.86 GiB 9.43 GiB
GC Limit 7.81 GiB 7.81 GiB
GC Collections 3,675 3,552
GC Collected Objects 218,476,127 211,313,164
Heap Start Allocated 3.35 MiB 3.35 MiB
Heap End Allocated 3.35 MiB 3.35 MiB
Heap Delta Allocated 128 B 128 B

Measured on ubuntu-latest x64.

@github-actions

Copy link
Copy Markdown
Contributor

Benchmark Results

430 benchmarks

Interpreted: 🟢 13 improved · 🔴 214 regressed · 203 unchanged · avg -7.1%
Bytecode: 🟢 40 improved · 🔴 41 regressed · 349 unchanged · avg +1.3%

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

Deterministic profile diff

Deterministic profile diff: no significant changes.

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

@frostney frostney marked this pull request as ready for review June 24, 2026 18:20
@coderabbitai coderabbitai Bot added bug Something isn't working spec compliance Mismatch against official JavaScript/TypeScript specification labels Jun 24, 2026
@github-actions

Copy link
Copy Markdown
Contributor

test262 Conformance

🚫 Regression vs cached main baseline. 2 previously-passing test(s) now fail; pass count Δ +36. This run blocks merge — see "Newly failing" below.

Category Run Passed Δ Pass Failed Pass-rate Δ Rate
built-ins 23,643 22,519 +4 1,124 95.2% ±0pp
harness 116 116 ±0 0 100.0% ±0pp
intl402 3,341 3,332 -2 9 99.7% -0.1pp
language 23,711 23,706 +34 5 100.0% +0.1pp
staging 1,482 1,103 ±0 377 74.4% ±0pp
total 52,293 50,776 +36 1,515 97.1% +0.1pp

Areas closest to 100%

Area Pass rate Δ vs main Passing
built-ins/TypedArray 99.9% ±0pp 1,445 / 1,446
intl402/Temporal 99.8% -0.1pp 2,024 / 2,029
built-ins/Object 99.7% ±0pp 3,401 / 3,411
Per-test deltas (+38 / -2)

Newly failing (2):

  • intl402/Temporal/ZonedDateTime/prototype/hoursInDay/dst-less-than-hour.js
  • intl402/Temporal/ZonedDateTime/prototype/hoursInDay/same-date-starts-twice.js

Newly passing (38):

  • built-ins/ArrayBuffer/prototype/transferToImmutable/new-length-coercion.js
  • built-ins/Number/prototype/toExponential/undefined-fractiondigits.js
  • built-ins/Number/string-binary-literal.js
  • built-ins/Number/string-octal-literal.js
  • language/expressions/call/tco-call-args.js
  • language/expressions/call/tco-member-args.js
  • language/expressions/call/tco-non-eval-function-dynamic.js
  • language/expressions/call/tco-non-eval-function.js
  • language/expressions/call/tco-non-eval-global.js
  • language/expressions/call/tco-non-eval-with.js
  • language/expressions/coalesce/tco-pos-null.js
  • language/expressions/coalesce/tco-pos-undefined.js
  • language/expressions/comma/tco-final.js
  • language/expressions/conditional/tco-cond.js
  • language/expressions/conditional/tco-pos.js
  • language/expressions/logical-and/tco-right.js
  • language/expressions/logical-or/tco-right.js
  • language/expressions/tagged-template/tco-call.js
  • language/expressions/tagged-template/tco-member.js
  • language/expressions/tco-pos.js
  • language/statements/block/tco-stmt-list.js
  • language/statements/block/tco-stmt.js
  • language/statements/do-while/tco-body.js
  • language/statements/for/tco-const-body.js
  • language/statements/for/tco-let-body.js
  • language/statements/for/tco-lhs-body.js
  • language/statements/for/tco-var-body.js
  • language/statements/if/tco-else-body.js
  • language/statements/if/tco-if-body.js
  • language/statements/labeled/tco.js
  • language/statements/return/tco.js
  • language/statements/switch/tco-case-body-dflt.js
  • language/statements/switch/tco-case-body.js
  • language/statements/switch/tco-dftl-body.js
  • language/statements/try/tco-catch-finally.js
  • language/statements/try/tco-catch.js
  • language/statements/try/tco-finally.js
  • language/statements/while/tco-body.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 merged commit d01f7bd into main Jun 24, 2026
13 of 14 checks passed
@frostney frostney deleted the claude/compassionate-rhodes-424905 branch June 24, 2026 19:56
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.

Deduplicate string-to-number parsing across runtime and compile-time conversion

1 participant