Skip to content

perf(cli): mimalloc global allocator + build ariadne SourceCache once per diagnostic batch - #4049

Closed
hellovai wants to merge 1 commit into
canaryfrom
perf/reland-cli-alloc-diag-render
Closed

perf(cli): mimalloc global allocator + build ariadne SourceCache once per diagnostic batch#4049
hellovai wants to merge 1 commit into
canaryfrom
perf/reland-cli-alloc-diag-render

Conversation

@hellovai

@hellovai hellovai commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Re-lands the baml_cli slice of the cold-compile performance audit (#4016, commit c1466f3), re-derived against current canary. Two independent changes:

  1. mimalloc as baml_cli's global allocator. The compiler workload is dominated by small short-lived allocations (Ty trees, Vecs, SmolStrs); system malloc measured ~35% of remaining single-threaded CPU in the original audit.
  2. Build the ariadne SourceCache once per diagnostic batch in render_diagnostics instead of once per diagnostic (each Source::from computes a line index over every project file), threading it as &mut through render_ariadne / render_report_to_string. Rendered output bytes are unchanged.

Measurements

CLI wall time on the warning-heavy corpus (baml check crates/baml_tests/baml_src, ~100 warnings), disk cache disabled via BAML_NO_BYTECODE_CACHE=1 + fresh BAML_CACHE_DIR, release builds of clean canary (2660b8b) vs. this branch, alternated in one hyperfine invocation:

Benchmark 1: BEFORE
  Time (mean ± σ):      3.947 s ±  0.587 s    [User: 3.118 s, System: 0.079 s]
  Range (min … max):    3.080 s …  5.032 s    10 runs

Benchmark 2: AFTER
  Time (mean ± σ):      1.304 s ±  0.280 s    [User: 1.182 s, System: 0.037 s]
  Range (min … max):    1.119 s …  2.012 s    10 runs

Summary
  AFTER ran
    3.02 ± 0.79 times faster than BEFORE

The benchmark machine was under heavy background load, hence the wide σ; user CPU time (3.12 s → 1.18 s, ~2.6x) is load-independent and consistent across all runs.

Cache-verify gate (#3924 compatibility)

Cached diagnostics are replayed byte-for-byte on cache hits, so rendered output must not change. Verified with BAML_CACHE_VERIFY=1 and a fresh BAML_CACHE_DIR (cache enabled), two runs each on before/after binaries so the second run replays cached diagnostics:

  • no divergence reported, all runs exit 0;
  • captured stdout+stderr of before vs. after binaries is byte-identical (only the wall-time suffix of the final "Finished checked 77 file(s) in Ns" status line differs between runs);
  • run 1 (cold) vs. run 2 (cached replay) output identical for both binaries.

Tests

  • cargo test --workspace: passes. (One caveat: three targets initially failed for environmental reasons on the shared bench machine — pack_e2e hit ENOSPC while the disk was full, the Python SDK cancellation tests need Python ≥ 3.11 (ExceptionGroup, asyncio.timeout) and uv had picked 3.10, and the TS fixtures were missing node_modules after the disk filled up. All three pass after freeing disk / UV_PYTHON=3.12 / re-running setup.sh, with no relation to this change.)
  • Targeted re-run on the rebased tip: baml_cli (385 tests), baml_compiler_diagnostics (18), baml_project — all pass.
  • Pre-commit hooks (cargo fmt, cargo stow, workspace clippy -D warnings) pass.
  • No snapshot changes.

Notes

Summary by CodeRabbit

  • Performance
    • Improved cold-start performance for baml check and baml build.
    • Improved rendering performance when displaying multiple compiler diagnostics.
    • Reduced repeated processing while generating Ariadne-formatted diagnostic output.
  • Bug Fixes
    • Preserved existing fallback behavior when a diagnostic cannot be rendered.

… per diagnostic batch

Two independent wins for cold  /  wall time,
re-derived from the compiler2 cold-compile audit (#4016):

- baml_cli now sets mimalloc as its global allocator. The compiler
  workload is dominated by small short-lived allocations (Ty trees,
  Vecs, SmolStrs); system malloc measured ~35% of remaining
  single-threaded CPU in the original audit.

- render_diagnostics builds the ariadne SourceCache (a line index over
  every project file) once per batch instead of once per diagnostic,
  threading it as &mut through render_ariadne /
  render_report_to_string. Rendered bytes are unchanged, so cached
  diagnostics from the #3924 disk cache replay identically
  (BAML_CACHE_VERIFY verified).

Co-authored-by: Cursor <cursoragent@cursor.com>
@cursor

cursor Bot commented Jul 16, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@vercel

vercel Bot commented Jul 16, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
beps Ready Ready Preview, Comment Jul 16, 2026 2:19am
promptfiddle Ready Ready Preview, Comment Jul 16, 2026 2:19am
promptfiddle2 Ready Ready Preview, Comment Jul 16, 2026 2:19am

Request Review

@github-actions

Copy link
Copy Markdown

⏭️ Performance benchmarks were skipped

Perf benchmarks (CodSpeed) are opt-in on pull requests — they no longer run on every push. They always run automatically after merge to canary/main.

To run them on this PR, do any of the following, then push a commit (or re-run CI):

  • Add RUN_CODSPEED=1 to the PR description, or
  • Include run-perf or /perf in the PR title or any commit message.

@vercel
vercel Bot temporarily deployed to Preview – beps July 16, 2026 01:58 Inactive
@coderabbitai

coderabbitai Bot commented Jul 16, 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: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 3b3dc087-c05e-48e5-b761-e23beee0298e

📥 Commits

Reviewing files that changed from the base of the PR and between 11e75dc and 32e0507.

⛔ Files ignored due to path filters (1)
  • baml_language/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (4)
  • baml_language/Cargo.toml
  • baml_language/crates/baml_cli/Cargo.toml
  • baml_language/crates/baml_cli/src/main.rs
  • baml_language/crates/baml_compiler_diagnostics/src/render.rs

📝 Walkthrough

Walkthrough

The CLI now uses mimalloc as its global allocator. Ariadne diagnostic rendering creates a source cache once and reuses it across single or batch rendering paths.

Changes

Performance updates

Layer / File(s) Summary
CLI allocator integration
baml_language/Cargo.toml, baml_language/crates/baml_cli/Cargo.toml, baml_language/crates/baml_cli/src/main.rs
Adds the pinned mimalloc workspace dependency, enables it in baml_cli, and configures it as the global allocator.
Shared Ariadne source cache
baml_language/crates/baml_compiler_diagnostics/src/render.rs
Creates and reuses SourceCache across Ariadne diagnostic rendering while preserving concise-format rendering and existing error fallback behavior.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: antoniosarosi, sxlijin

Poem

I’m a rabbit with a cache to share,
And mimalloc bouncing through the air.
Diagnostics stream with sources bright,
The CLI compiles cold and light.
Hop, hop—fewer builds anew!

🚥 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 clearly summarizes the two main performance changes: mimalloc in the CLI and shared Ariadne SourceCache batching.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch perf/reland-cli-alloc-diag-render

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.

@vercel
vercel Bot temporarily deployed to Preview – promptfiddle2 July 16, 2026 02:05 Inactive
@github-actions

Copy link
Copy Markdown

Binary size checks passed

7 passed

Artifact Platform File Gzip Gated on Baseline Delta Status
baml-cli Linux 🔒 23.0 MB 9.8 MB file 22.8 MB +212.4 KB (+0.9%) OK
packed-program Linux 🔒 16.3 MB 6.8 MB file 16.3 MB +24.6 KB (+0.2%) OK
baml-cli macOS 🔒 17.7 MB 8.5 MB file 17.5 MB +185.9 KB (+1.1%) OK
packed-program macOS 🔒 12.6 MB 6.0 MB file 12.6 MB +32 B (+0.0%) OK
baml-cli Windows 🔒 19.1 MB 8.7 MB file 18.7 MB +398.8 KB (+2.1%) OK
packed-program Windows 🔒 13.5 MB 6.1 MB file 13.5 MB +5.6 KB (+0.0%) OK
bridge_wasm WASM 15.2 MB 🔒 4.3 MB gzip 4.3 MB +3.6 KB (+0.1%) OK

🔒 = the size this artifact is GATED on (ceiling + delta). Binaries gate on file size (installed binary); WASM gates on gzip (download size). The other size is shown for information only.


Generated by cargo size-gate · workflow run

@hellovai

Copy link
Copy Markdown
Contributor Author

Folded into the combined re-landing PR #4054 (per maintainer preference for a single PR post-tool-merge). Branch kept for provenance; individual before/after measurements remain in this PR's description.

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