Skip to content

Enable PGO for Linux x86-64 Ruff releases - #27570

Draft
charliermarsh wants to merge 5 commits into
mainfrom
charlie/ruff-pgo-prototype
Draft

Enable PGO for Linux x86-64 Ruff releases#27570
charliermarsh wants to merge 5 commits into
mainfrom
charlie/ruff-pgo-prototype

Conversation

@charliermarsh

@charliermarsh charliermarsh commented Aug 7, 2026

Copy link
Copy Markdown
Member

Summary

Enable LLVM instrumentation-based profile-guided optimization (PGO) for native Linux x86-64 Ruff release builds. This runs alongside the existing fat LTO; it does not use LLVM BOLT. We build an instrumented, stripped release binary, train check and format on an immutable corpus of real Python ecosystem projects, merge the profiles with the active Rust toolchain's llvm-profdata, and feed the result into the existing maturin build. The optimized executable is reused for both the wheel and standalone archive.

The training corpus contains 502 tracked Python and stub files totaling 5.67 MB:

Project Source Files
pytest src/_pytest 77
HTTPX httpx 23
FastAPI fastapi 48
AnyIO src/anyio 43
pip src/pip/_internal 153
Sphinx Selected builders, autodoc extensions, and Python domains 55
Astropy astropy/units, excluding tests 49
typeshed Selected asyncio, collections, and requests stubs 54

Each project is pinned to a validated, full Git commit SHA and fetched over HTTPS using shallow, blob-filtered sparse checkouts. We disable Git hooks, avoid installing dependencies or executing project code, skip tests and vendored dependencies, retry transient Git failures, and include only clean tracked source files. Existing checkouts must retain their expected HTTPS origin and are restored to their pinned revisions before reuse.

The dependency-free helper declares its Python requirements with PEP 723 inline metadata. Lint and formatter workloads produce separately labeled profiles, and both must contain complete data before their profiles are atomically merged.

The training corpus matches ty's eight pinned ecosystem projects and excludes Prefect, which is reserved for ty's official benchmark suite. The projects do not overlap Ruff's Criterion benchmark fixtures or the held-out Django, pandas, scikit-learn, SciPy, and SymPy evaluation projects. The helper rejects cross-target execution, preserves existing Rust flags, and avoids mismatched Apple-clang profiling when run locally on macOS. Other release targets are unchanged.

Linux x86-64 performance

Compared production non-PGO and PGO release binaries with identical Ruff 0.16.2 source, all 32 runtime workspace crates, Cargo.lock, Rust toolchain, and release configuration. Benchmarks covered 5,396 held-out Python and stub files totaling 90.57 MB and ran on eight distinct physical AMD EPYC cores with three warmups and twelve alternating baseline/PGO pairs per workload.

Held-out project ruff check ruff format
Django 10.9% faster 6.6% faster
pandas 16.3% faster 9.7% faster
scikit-learn 10.8% faster 7.9% faster
SciPy 14.7% faster 5.6% faster
SymPy 17.1% faster 11.4% faster
Geometric mean 14.0% faster 8.3% faster

Across all ten workloads, wall time improved by 11.2% and CPU time improved by 14.3%. PGO won 117 of 120 wall-time comparisons and all 120 CPU-time comparisons. The stripped Linux binary decreased from 27.96 MB to 26.23 MB, a 6.2% reduction. The non-PGO release build took 7m22s; the PGO pipeline took 15m14s (8m35s instrumented training plus 6m39s optimized wheel), an increase of 7m52s or 2.07×.

A follow-up comparison of the original nine-project corpus and the aligned eight-project corpus used production macOS ARM64 binaries, the same five held-out projects, and 12 alternating pairs. Performance was effectively unchanged: the eight-project corpus was 0.16% faster in wall time and used 0.12% less CPU; its standalone release archive was 0.10% larger.

Related to #7055.

@astral-sh-bot

astral-sh-bot Bot commented Aug 7, 2026

Copy link
Copy Markdown

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Formatter (stable)

✅ ecosystem check detected no format changes.

Formatter (preview)

✅ ecosystem check detected no format changes.

Comment on lines +243 to +254
- name: "Install LLVM profiling tools"
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
run: rustup component add llvm-tools-preview
- name: "Train PGO Ruff"
if: ${{ matrix.target == 'x86_64-unknown-linux-gnu' }}
run: |
python scripts/build_ruff_pgo.py \
--target "${{ matrix.target }}" \
--target-dir "${{ github.workspace }}/target/ruff-pgo" \
--train-only

echo "RUSTFLAGS=${RUSTFLAGS:+${RUSTFLAGS} }-Cprofile-use=${{ github.workspace }}/target/ruff-pgo/ruff.profdata" >> "$GITHUB_ENV"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand it, we can also add i686-pc-windows-msvc, x86_64-pc-windows-msvc, aarch64-apple-darwin, x86_64-apple-darwin, aarch64-unknown-linux-gnu, and i686-unknown-linux-gnu

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also build PGO build wheels for my library, and I don't think I've had any problems with these targets

Windows · macOS · manylinux

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, yes they would all be covered. This is just experimental right now to gather data.

@charliermarsh
charliermarsh force-pushed the charlie/ruff-pgo-prototype branch from ff08211 to a752a11 Compare August 7, 2026 20:31
@charliermarsh charliermarsh changed the title Prototype profile-guided optimization for Ruff releases Enable PGO for Linux x86-64 Ruff releases Aug 7, 2026
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.

2 participants