Skip to content

[turbopack] Optimize the implementation of AutoMap/AutoSet #95694

Open
lukesandberg wants to merge 5 commits into
canaryfrom
07-10-auto-hash-map_back_automap_list_with_a_bounded_inlinevec_instead_of_smallvec
Open

[turbopack] Optimize the implementation of AutoMap/AutoSet #95694
lukesandberg wants to merge 5 commits into
canaryfrom
07-10-auto-hash-map_back_automap_list_with_a_bounded_inlinevec_instead_of_smallvec

Conversation

@lukesandberg

@lukesandberg lukesandberg commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Optimize the implementation of AutoMap/AutoSet.

Previously the List variant was backed by a SmallVec in inline mode, which needs at least 24 bytes of header (len, cap, ptr — all usize) even though the list never holds more than 32 elements.

This replaces it with the TinyVec struct from turbo-tasks-backend which is now enhanced with support for an inline array. The length is a NonZeroU8, which reserves a niche the AutoMap enum folds its discriminant into — dropping AutoMap's minimum size to 16 bytes. This in turn shrinks TaskStorage and the LazyField enum. Some inline structs in TaskStorage are increased in size so we keep the 128 byte footprint

Copy link
Copy Markdown
Contributor Author

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Stats from current PR

Warning

No stats were collected for Webpack because its stats job did not complete (it failed, was cancelled, or timed out). The results below only cover the bundlers that finished.

✅ No significant changes detected

📊 All Metrics
📖 Metrics Glossary

Dev Server Metrics:

  • Listen = TCP port starts accepting connections
  • First Request = HTTP server returns successful response
  • Cold = Fresh build (no cache)
  • Warm = With cached build artifacts

Build Metrics:

  • Fresh = Clean build (no .next directory)
  • Cached = With existing .next directory

Change Thresholds:

  • Time: Changes < 50ms AND < 10%, OR < 2% are insignificant
  • Size: Changes < 1KB AND < 1% are insignificant
  • All other changes are flagged to catch regressions

⚡ Dev Server

Metric Canary PR Change Trend
Cold (Listen) 813ms 811ms ▁▁▁▁▂
Cold (Ready in log) 778ms 775ms ▁▁▁▁▁
Cold (First Request) 1.300s 1.288s ▁▁▁▁▁
Warm (Listen) 812ms 762ms ▁▁▁▁▁
Warm (Ready in log) 775ms 765ms ▁▁▁▁▁
Warm (First Request) 1.275s 1.289s ▁▁▁▁▁

⚡ Production Builds

Metric Canary PR Change Trend
Fresh Build 4.843s 5.044s ▁▁▁▁▁
Cached Build 4.969s 5.109s ▁▁▁▁▂
📦 Production Builds (Webpack) (Legacy)

📦 Production Builds (Webpack)

Metric Canary PR Change Trend
node_modules Size 514 MB 514 MB ▁▁▁▁▁
📦 Bundle Sizes

Bundle Sizes

⚡ Turbopack

Client

Main Bundles
Canary PR Change
00ef4gy8b5wxj.js gzip 157 B N/A -
03gmyxr7dukvs.js gzip 10.3 kB N/A -
040t1q17lo593.js gzip 8.77 kB N/A -
05js0p06ql0ws.js gzip 162 B N/A -
0bb0vtp8dwsez.js gzip 450 B N/A -
0cz1d0mv5g_q7.js gzip 39.4 kB 39.4 kB
0ga6rcwbclepx.js gzip 158 B N/A -
0l0sr6gau5xjn.js gzip 3.53 kB N/A -
0nxqz3q165m2l.js gzip 220 B N/A -
0qr-1tnb7_hg5.js gzip 5.72 kB N/A -
0su3oj-wd_f24.js gzip 157 B N/A -
0uilzvklme4ea.js gzip 8.76 kB N/A -
0v-to2419kft6.js gzip 71.1 kB N/A -
0z0y83mfx-l-h.js gzip 10 kB N/A -
15ok8ydf274z0.js gzip 10.6 kB N/A -
16cqqcigykfea.js gzip 13.6 kB N/A -
17h18zxt1915l.js gzip 1.46 kB N/A -
1b6ps5k3qbc9v.js gzip 168 B N/A -
1elt1qium-r2m.css gzip 115 B 115 B
1fq1h7dxad4cv.js gzip 9.44 kB N/A -
1fym-adbk_69_.js gzip 13.1 kB N/A -
1g80-jfls9qyr.js gzip 13.2 kB N/A -
1gav7nfh4y8ln.js gzip 8.76 kB N/A -
22sajk3amu-ua.js gzip 45 kB N/A -
2c0gxmllklfeh.js gzip 155 B N/A -
2cm1e61lu646w.js gzip 155 B N/A -
2jicr0hpcz3x7.js gzip 154 B N/A -
2rypqffktcxqh.js gzip 8.69 kB N/A -
2te199gvbth0p.js gzip 154 B N/A -
2uqsizxtehgqf.js gzip 8.79 kB N/A -
2vzktdqwbijqc.js gzip 8.74 kB N/A -
2zh5c22cnhvwf.js gzip 155 B N/A -
304gh1b2mfj2-.js gzip 65.5 kB N/A -
35dyc4njdvspw.js gzip 156 B N/A -
39ubradsr4gzy.js gzip 158 B N/A -
3c244akvx_-be.js gzip 8.74 kB N/A -
3dmlemitx3ef3.js gzip 2.29 kB N/A -
3pq0q6ik66hi5.js gzip 162 B N/A -
3y193x4n8cq9d.js gzip 7.4 kB N/A -
4237vdj6eyslt.js gzip 8.7 kB N/A -
turbopack-06..2zci.js gzip 3.85 kB N/A -
turbopack-0l..vj57.js gzip 3.85 kB N/A -
turbopack-0y..khhu.js gzip 3.85 kB N/A -
turbopack-17..dk51.js gzip 3.83 kB N/A -
turbopack-1o..q_rp.js gzip 3.85 kB N/A -
turbopack-1t..txle.js gzip 3.85 kB N/A -
turbopack-1u..7swf.js gzip 3.85 kB N/A -
turbopack-1y..8r0a.js gzip 3.85 kB N/A -
turbopack-28..1rro.js gzip 3.85 kB N/A -
turbopack-29..--ev.js gzip 3.85 kB N/A -
turbopack-3-..e5qa.js gzip 3.85 kB N/A -
turbopack-31..np11.js gzip 3.85 kB N/A -
turbopack-3l..a73s.js gzip 3.86 kB N/A -
turbopack-3z..yq_9.js gzip 3.85 kB N/A -
00tc16j5-eos9.js gzip N/A 1.46 kB -
0130eu77j0h59.js gzip N/A 155 B -
04joe4zmayj76.js gzip N/A 159 B -
05efbq2jv23b5.js gzip N/A 155 B -
05tax4x1rfda4.js gzip N/A 7.4 kB -
0ci8x4-0ug8pc.js gzip N/A 71.1 kB -
0d9rpn6i4_zpx.js gzip N/A 160 B -
0gaw1gmpwuwkn.js gzip N/A 8.8 kB -
12zyjjmq4oad1.js gzip N/A 5.72 kB -
1hefztyduchdh.js gzip N/A 156 B -
1k9cc4-gpa2cx.js gzip N/A 13.1 kB -
1n59uogejo81s.js gzip N/A 10.3 kB -
1npei3hlexdv3.js gzip N/A 9.99 kB -
1ssuiwj_rnpc5.js gzip N/A 8.77 kB -
1zfs8m9y4a5zq.js gzip N/A 152 B -
2-phc9obd3nyd.js gzip N/A 8.77 kB -
24utq57r3l1cw.js gzip N/A 8.7 kB -
2d_vc-5g35ich.js gzip N/A 155 B -
2fhjq6ek3srmr.js gzip N/A 8.69 kB -
2g0t7upz_v-hf.js gzip N/A 10.6 kB -
2ia9qqy99aie9.js gzip N/A 13.6 kB -
2m58iubo3_2om.js gzip N/A 65.5 kB -
2oza28kdqvoay.js gzip N/A 8.74 kB -
2x7r100b7ytej.js gzip N/A 168 B -
2zh8-mmhujy8o.js gzip N/A 2.29 kB -
2znh0hgl912gx.js gzip N/A 155 B -
30h_m0irj-q6p.js gzip N/A 221 B -
359s3sl8kxyzu.js gzip N/A 156 B -
37ejbfx1u9lpo.js gzip N/A 8.75 kB -
38c63ct4i1cy7.js gzip N/A 449 B -
395ew4vducf52.js gzip N/A 154 B -
3bov4yvn0_jo5.js gzip N/A 157 B -
3hd1us4ordyc9.js gzip N/A 13.2 kB -
3jimpal3lvz5e.js gzip N/A 9.44 kB -
3ns42zoevxrsp.js gzip N/A 45 kB -
3su6a4l8jbfth.js gzip N/A 3.53 kB -
3wb4pe4z4-aim.js gzip N/A 8.77 kB -
41z0m_6bo_9ke.js gzip N/A 155 B -
turbopack-05..tq1r.js gzip N/A 3.85 kB -
turbopack-0c..kyer.js gzip N/A 3.84 kB -
turbopack-0o..5lk5.js gzip N/A 3.83 kB -
turbopack-0t..ilm7.js gzip N/A 3.85 kB -
turbopack-17..m634.js gzip N/A 3.85 kB -
turbopack-19..1c1c.js gzip N/A 3.85 kB -
turbopack-1j..f3i6.js gzip N/A 3.85 kB -
turbopack-1q..obpn.js gzip N/A 3.85 kB -
turbopack-1z..7kul.js gzip N/A 3.85 kB -
turbopack-2g..1qrh.js gzip N/A 3.85 kB -
turbopack-2m..1z1h.js gzip N/A 3.85 kB -
turbopack-2y..nv-r.js gzip N/A 3.85 kB -
turbopack-35..jnn_.js gzip N/A 3.86 kB -
turbopack-3j..38kl.js gzip N/A 3.85 kB -
Total 448 kB 448 kB ⚠️ +20 B

Server

Middleware
Canary PR Change
middleware-b..fest.js gzip 730 B 723 B
Total 730 B 723 B ✅ -7 B
Build Details
Build Manifests
Canary PR Change
_buildManifest.js gzip 434 B 433 B
Total 434 B 433 B ✅ -1 B

🔄 Shared (bundler-independent)

Runtimes
Canary PR Change
app-page-exp...dev.js gzip 361 kB 361 kB
app-page-exp..prod.js gzip 199 kB 199 kB
app-page-tur...dev.js gzip 361 kB 361 kB
app-page-tur..prod.js gzip 199 kB 199 kB
app-page-tur...dev.js gzip 357 kB 357 kB
app-page-tur..prod.js gzip 197 kB 197 kB
app-page.run...dev.js gzip 358 kB 358 kB
app-page.run..prod.js gzip 197 kB 197 kB
app-route-ex...dev.js gzip 79.1 kB 79.1 kB
app-route-ex..prod.js gzip 53.6 kB 53.6 kB
app-route-tu...dev.js gzip 79.1 kB 79.1 kB
app-route-tu..prod.js gzip 53.6 kB 53.6 kB
app-route-tu...dev.js gzip 78.7 kB 78.7 kB
app-route-tu..prod.js gzip 53.4 kB 53.4 kB
app-route.ru...dev.js gzip 78.7 kB 78.7 kB
app-route.ru..prod.js gzip 53.3 kB 53.3 kB
dist_client_...dev.js gzip 324 B 324 B
dist_client_...dev.js gzip 326 B 326 B
dist_client_...dev.js gzip 318 B 318 B
dist_client_...dev.js gzip 317 B 317 B
pages-api-tu...dev.js gzip 45.2 kB 45.2 kB
pages-api-tu..prod.js gzip 34 kB 34 kB
pages-api.ru...dev.js gzip 45.2 kB 45.2 kB
pages-api.ru..prod.js gzip 33.9 kB 33.9 kB
pages-turbo....dev.js gzip 54.7 kB 54.7 kB
pages-turbo...prod.js gzip 39.6 kB 39.6 kB
pages.runtim...dev.js gzip 54.7 kB 54.7 kB
pages.runtim..prod.js gzip 39.6 kB 39.6 kB
server.runti..prod.js gzip 65.2 kB 65.2 kB
use-cache-pr...dev.js gzip 71.4 kB 71.4 kB
use-cache-pr...dev.js gzip 71.4 kB 71.4 kB
use-cache-pr...dev.js gzip 69.7 kB 69.7 kB
use-cache-pr...dev.js gzip 69.7 kB 69.7 kB
Total 3.46 MB 3.46 MB
📎 Tarball URL
https://vercel-packages.vercel.app/next/commits/f7314ac22a788aa01e8989946c5ef32d19c59707/next

Commit: f7314ac

@github-actions

github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Tests Passed

Commit: f7314ac

@lukesandberg lukesandberg changed the title auto-hash-map: back AutoMap List with a bounded InlineVec instead of SmallVec [turbopack] Optimize the implementation of AutoMap/AutoSet Jul 10, 2026
…SmallVec

The List variant of AutoMap used SmallVec<[(K,V); I]>, whose header is
three usizes (length + heap pointer + capacity) even though AutoMap never
lets the inner buffer spill on its own — it converts List -> Map before
exceeding MAX_LIST_SIZE. The pointer/capacity words were dead weight and
SmallVec's plain-usize length exposed no niche, so the AutoMap enum also
paid for a separate discriminant word. As a result AutoSet/AutoMap were
32 bytes regardless of the inline-capacity const I.

Replace it with InlineVec<T, I>: a bounded small-vec (still heap-spills up
to MAX_LIST_SIZE, preserving today's spill semantics) with a two-byte
header — len: NonZeroU8 (storing actual_len + 1) and cap: u8 — overlapping
the inline array and heap pointer in a union. The NonZeroU8 niche lets the
enclosing AutoMap enum fold its List/Map discriminant in for free.

Sizes now shrink with I: AutoSet<TaskId, 0> 32 -> 16, AutoSet<TaskId, 3>
32 -> 24. Validated with unit tests (niche/size asserts + drop accounting)
and clean under Miri with strict provenance.
@lukesandberg lukesandberg marked this pull request as ready for review July 11, 2026 07:28
@lukesandberg lukesandberg requested a review from bgw July 11, 2026 07:29
@lukesandberg lukesandberg force-pushed the 07-10-auto-hash-map_back_automap_list_with_a_bounded_inlinevec_instead_of_smallvec branch from c1fea49 to f7314ac Compare July 11, 2026 08:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant