Skip to content

perf(formatter_core): stage IR buffers on the heap to reduce arena memory#24582

Merged
graphite-app[bot] merged 1 commit into
mainfrom
07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory
Jul 22, 2026
Merged

perf(formatter_core): stage IR buffers on the heap to reduce arena memory#24582
graphite-app[bot] merged 1 commit into
mainfrom
07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory

Conversation

@leaysgur

@leaysgur leaysgur commented Jul 16, 2026

Copy link
Copy Markdown
Member

Part of #24558

Adds HeapVecBuffer to oxc_formatter_core: a staging twin of VecBuffer that grows on a pooled heap vector and moves the finished sequence into the arena as one exactly-sized allocation.

Converted JS formatter call sites: Formatter::intern, BestFitting variant construction, and the three grouped-call-argument variant builders.

The other formatters would automatically benefit from this as well, and there was no need to make any individual changes.


TIL: antd.js is a bundled file and is not intended for general formatting.

@leaysgur
leaysgur requested a review from overlookmotel as a code owner July 16, 2026 03:23
@github-actions github-actions Bot added the A-formatter Area - Formatter label Jul 16, 2026

leaysgur commented Jul 16, 2026

Copy link
Copy Markdown
Member Author

How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent changes, fast-track this PR to the front of the merge queue

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@codspeed-hq

codspeed-hq Bot commented Jul 16, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 4.94%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 55 untouched benchmarks
⏩ 19 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation formatter[types.ts] 12.5 ms 11.8 ms +6.17%
Simulation formatter[App.tsx] 47.4 ms 45.7 ms +3.72%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing 07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory (d7cedab) with main (8eb9eca)2

Open in CodSpeed

Footnotes

  1. 19 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (7c46346) during the generation of this report, so 8eb9eca was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@oxc-guard

oxc-guard Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Oxfmt Ecosystem CI

suite oxfmt@latest main refs/pull/24582/head branch
cnpm/cnpmcore
fuma-nama/fumadocs
vercel/turborepo
eggjs/egg
monkeytypegame/monkeytype
AmanVarshney01/create-better-t-stack
formatjs/formatjs
actualbudget/actual
fastify/fastify-vite
vuejs/pinia
getsentry/sentry-javascript
tale/headplane
openclaw/openclaw
huggingface/huggingface.js
cloudflare/agents
rolldown/rolldown
npmx-dev/npmx.dev
lichess-org/lila
aidenybai/react-grab
vuejs/core
mastodon/mastodon
cloudflare/workers-sdk
dyad-sh/dyad
mantinedev/mantine
Comfy-Org/ComfyUI_frontend ⚠️

💥 = panic, ⚠️ = error e.g. parse error (main/branch columns: only new errors), ❌ = diff or exit code mismatch, 🟨 = differs from oxfmt@latest (merged-but-unreleased changes)

@leaysgur
leaysgur force-pushed the 07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory branch from bf07076 to aa1921c Compare July 16, 2026 05:04
@leaysgur
leaysgur force-pushed the 07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory branch from aa1921c to 12a1158 Compare July 17, 2026 06:03
@leaysgur
leaysgur force-pushed the 07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory branch from 12a1158 to 8039aca Compare July 21, 2026 06:11
@leaysgur
leaysgur force-pushed the 07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory branch 2 times, most recently from c880bce to d7cedab Compare July 22, 2026 05:04
@graphite-app graphite-app Bot added the 0-merge Merge with Graphite Merge Queue label Jul 22, 2026
@graphite-app

graphite-app Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Merge activity

…mory (#24582)

Part of #24558

Adds `HeapVecBuffer` to `oxc_formatter_core`: a staging twin of `VecBuffer` that grows on a pooled heap vector and moves the finished sequence into the arena as one exactly-sized allocation.

Converted JS formatter call sites: `Formatter::intern`, `BestFitting` variant construction, and the three grouped-call-argument variant builders.

The other formatters would automatically benefit from this as well, and there was no need to make any individual changes.

---

TIL: `antd.js` is a bundled file and is not intended for general formatting.
@graphite-app
graphite-app Bot force-pushed the 07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory branch from d7cedab to c191f51 Compare July 22, 2026 06:32
graphite-app Bot pushed a commit that referenced this pull request Jul 22, 2026
The JSX child-list builders (`MultilineBuilder` / `FlatBuilder` in `child_list.rs`) were the last IR staging path still growing vectors in the arena.

They accumulate elements across the whole child-list loop while arbitrary child content is
formatted in between, so every growth stranded its old allocation (the same pattern #24582 removed from `intern` / `BestFitting` / grouped arguments).

They can't use `HeapVecBuffer`: the flat and multiline builders write *alternately* for each child, which would interleave their segments in the shared scratch vector and break its LIFO watermark discipline. The thread-local cache behind it has no such requirement though.

So each builder now checks out its own `ScratchBuffer` and writes into it through a small private `Buffer` adapter (`ChildListBuffer`); the finished result reaches the arena as one exactly-sized copy via the new `Formatter::intern_elements`, which clears the source so its capacity returns to the cache on drop.

Now arena reallocs for `RadixUIAdoptionSection.jsx` is 0.
@graphite-app
graphite-app Bot merged commit c191f51 into main Jul 22, 2026
30 checks passed
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Jul 22, 2026
@graphite-app
graphite-app Bot deleted the 07-16-perf_formatter_core_stage_ir_buffers_on_the_heap_to_reduce_arena_memory branch July 22, 2026 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-formatter Area - Formatter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant