astral-sh / uv

An extremely fast Python package and project manager, written in Rust.
https://docs.astral.sh/uv
Apache License 2.0
25.04k stars 724 forks source link

perf: `uv build` is slower on the second run compared to `uvx hatch build` #7062

Open pplmx opened 1 month ago

pplmx commented 1 month ago

Reproduce Steps

1. Using uv build

cookiecutter gh:x-pt/template --directory template/py --no-input && \
cd my-awesome-project && \
uv sync && \
time uv build && \
time uv build && \
time uv build && \
time uv build && \
cd .. && rm -fr my-awesome-project

2. Using uvx hatch build

cookiecutter gh:x-pt/template --directory template/py --no-input && \
cd my-awesome-project && \
uv sync && \
time uvx hatch build && \
time uvx hatch build && \
time uvx hatch build && \
time uvx hatch build && \
cd .. && rm -fr my-awesome-project

Additional Information

charliermarsh commented 1 month ago

I don't know if there's a ton for us to optimize here but we can look into it. The majority of the time is in invoking the Python interpreter and calling the build backend.

charliermarsh commented 1 month ago

There's so little work happening here that my guess is Hatch benefits from building a project that uses hatchling as its own backend, so there's less overhead? Like, we're probably paying overhead to invoke Python several times.

If you compare uv build to python -m build --installer uv, I believe uv build is faster (so, e.g., if you try the same thing with a setuptools project, I would guess uv will be faster).

We'll get similar benefits when we build our own build backend!

pplmx commented 1 month ago

Expect the UV's own build backend to be used. ❤️

henryiii commented 1 month ago

If you compare uv build to python -m build --installer uv, I believe uv build is faster

Hopefully @matthewfeickert doesn't mind me stealing this from him:

$ time pipx run build .
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
  - hatch-vcs>=0.3.0
  - hatchling>=1.13.0
* Getting build dependencies for sdist...
* Building sdist...
* Building wheel from sdist
* Creating isolated environment: venv+pip...
* Installing packages in isolated environment:
  - hatch-vcs>=0.3.0
  - hatchling>=1.13.0
* Getting build dependencies for wheel...
* Building wheel...
Successfully built pyhf-0.7.1.dev273.tar.gz and pyhf-0.7.1.dev273-py3-none-any.whl

real    0m3.087s
user    0m2.299s
sys 0m0.282s
$ rm -rf dist && time pipx run build --installer uv .
* Creating isolated environment: venv+uv...
* Using external uv from /home/feickert/.pyenv/shims/uv
* Installing packages in isolated environment:
  - hatch-vcs>=0.3.0
  - hatchling>=1.13.0
* Getting build dependencies for sdist...
* Building sdist...
* Building wheel from sdist
* Creating isolated environment: venv+uv...
* Using external uv from /home/feickert/.pyenv/shims/uv
* Installing packages in isolated environment:
  - hatch-vcs>=0.3.0
  - hatchling>=1.13.0
* Getting build dependencies for wheel...
* Building wheel...
Successfully built pyhf-0.7.1.dev273.tar.gz and pyhf-0.7.1.dev273-py3-none-any.whl

real    0m1.214s
user    0m0.971s
sys 0m0.278s
$ rm -rf dist
$ time uv build
Building source distribution...
Building wheel from source distribution...
Successfully built dist/pyhf-0.7.1.dev273.tar.gz and dist/pyhf-0.7.1.dev273-py3-none-any.whl

real    0m0.799s
user    0m0.634s
sys 0m0.193s

And if there was a Rust build backend (like maturin) and uv could skip Python entirely when calling it (like maturin the command does), I'd expect uv build would be ridiculously fast in that case. But under a second isn't bad. :) For a built package though, the compiler takes most of the time.

charliermarsh commented 1 month ago

...uv could skip Python entirely when calling it (like maturin the command does), I'd expect uv build would be ridiculously fast in that case.

Yeah this is one of the motivations. Would be really cool!