Skip to content

Harden OrderedStringMap tombstone compaction#148

Merged
frostney merged 1 commit into
mainfrom
fix/issue-103-ordered-string-map-tombstones
Mar 31, 2026
Merged

Harden OrderedStringMap tombstone compaction#148
frostney merged 1 commit into
mainfrom
fix/issue-103-ordered-string-map-tombstones

Conversation

@frostney
Copy link
Copy Markdown
Owner

@frostney frostney commented Mar 31, 2026

Summary

  • track deleted buckets in TOrderedStringMap and reset the counter on rebuild paths
  • compact the table after delete-heavy phases to keep probe sequences bounded and decrement the counter when a tombstone slot is reused
  • add Pascal unit coverage for tombstone reuse and delete-heavy compaction, and document the behavior

Testing

  • ./format.pas
  • ./build.pas clean tests testrunner
  • for t in build/Goccia.*.Test; do ""; done
  • ./build/TestRunner tests --no-progress

Closes #103

Summary by CodeRabbit

  • New Features

    • Improved OrderedStringMap performance with automatic compaction after heavy deletion operations, ensuring efficient probe chain management.
  • Tests

    • Added comprehensive test suite covering deletion and reinsertion scenarios.
  • Documentation

    • Updated documentation to reflect deletion tracking and compaction behavior.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 25abeac7-eaac-4703-9722-a6b336ba03d9

📥 Commits

Reviewing files that changed from the base of the PR and between f811f42 and b242138.

📒 Files selected for processing (3)
  • docs/code-style.md
  • units/Goccia.OrderedStringMap.Test.pas
  • units/OrderedStringMap.pas

📝 Walkthrough

Walkthrough

This change implements deleted-bucket tracking in TOrderedStringMap<TValue> by adding a FDeletedCount field and compaction logic. When the ratio of deleted slots exceeds a threshold, the map now triggers compaction to keep probe chains bounded, alongside updates to documentation and comprehensive test coverage.

Changes

Cohort / File(s) Summary
Documentation
docs/code-style.md
Updated TOrderedStringMap<V> entry to document tracking of deleted buckets and post-delete-heavy-phase compaction behavior.
Core Implementation
units/OrderedStringMap.pas
Added FDeletedCount field and DeletedCount property; introduced DeletedSlotsNeedCompaction check; updated Add, Remove, Create, Clear, and Rehash methods to track, reset, and trigger compaction based on deleted-slot ratio.
Test Suite
units/Goccia.OrderedStringMap.Test.pas
New test program with two test cases: one verifies bucket reuse and DeletedCount clearing after removal/insertion; another verifies delete-heavy behavior and tombstone compaction effects on DeletedCount and key ordering.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 Hop through buckets, swift and true,
When tombstones pile, we know what's due—
Compact them down, make probes unwind,
Deleted tracks cleaned, peace of mind!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically summarizes the main objective: hardening the OrderedStringMap by implementing tombstone compaction tracking and cleanup.
Linked Issues check ✅ Passed The pull request successfully implements all coding requirements from issue #103: FDeletedCount tracking, increment/decrement logic, clear on rebuild paths, and tombstone threshold compaction triggering.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #103: OrderedStringMap implementation, unit tests for tombstone behavior, and documentation updates explaining the new compaction mechanism.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/issue-103-ordered-string-map-tombstones

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

❤️ Share

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

@github-actions
Copy link
Copy Markdown
Contributor

Suite Timing

Suite Metric Interpreted Bytecode
Tests Total 3542 3542
Tests Passed 3501 ✅ 3542 ✅
Tests Skipped 41 0
Tests Execution 145.4ms 149.7ms
Tests Engine 303.4ms 533.3ms
Benchmarks Total 263 263
Benchmarks Duration 7.13min 6.28min

Measured on ubuntu-latest x64.

@github-actions
Copy link
Copy Markdown
Contributor

Benchmark Results

263 benchmarks

Interpreted: 🟢 13 improved · 🔴 146 regressed · 104 unchanged · avg -1.7%
Bytecode: 🟢 42 improved · 🔴 151 regressed · 70 unchanged · avg -3.7%

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

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 merged commit fe5c3f0 into main Mar 31, 2026
9 checks passed
@frostney frostney deleted the fix/issue-103-ordered-string-map-tombstones branch March 31, 2026 18:22
@frostney frostney added the bug Something isn't working label Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Follow-up] TOrderedStringMap: track FDeletedCount and trigger Compact/Rehash when tombstones dominate

1 participant