Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--use-pep517 appears to be significanly slower for small projects #10060

Closed
1 task done
zmanji opened this issue Jun 13, 2021 · 6 comments
Closed
1 task done

--use-pep517 appears to be significanly slower for small projects #10060

zmanji opened this issue Jun 13, 2021 · 6 comments
Labels
resolution: not a bug Determined as not a bug in pip type: bug A confirmed bug or unintended behavior

Comments

@zmanji
Copy link

zmanji commented Jun 13, 2021

Description

I have observed a performance regression in building wheels with --use-pep517 vs --no-use-pep517

Expected behavior

No significant performance change between --use-pep517 and --no-use-pep517

pip version

21.1.2

Python version

3.7.3

OS

Debian

How to Reproduce

To reproduce:

  1. git clone git@github.com:zmanji/git-squash.git
  2. Checkout e714352b532f2fdfc57b23df9b7cf8dc0fed34d6
  3. Install the benchmarking tool hyperfine

Run

hyperfine -w2 'pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --no-use-pep517' 'pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --use-pep517'

Observe that the only difference between to the two pip wheel commands is --no-use-pep517 vs --use-pep517. Also observe the in tree build feature is enabled.

Feel free to change -w2 to -w3 or higher to increase warmups

Output

With pip 21.1.2 and wheel 0.36.2

I see the following results

on macOS 11.4 with Python 3.9.4

Benchmark #1: pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --no-use-pep517
  Time (mean ± σ):      1.220 s ±  0.039 s    [User: 917.3 ms, System: 200.4 ms]
  Range (min … max):    1.191 s …  1.325 s    10 runs
 
Benchmark #2: pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --use-pep517
  Time (mean ± σ):      4.390 s ±  0.018 s    [User: 3.563 s, System: 0.618 s]
  Range (min … max):    4.360 s …  4.416 s    10 runs
 
Summary
  'pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --no-use-pep517' ran
    3.60 ± 0.12 times faster than 'pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --use-pep517'

on Debian Linux with Python 3.7.3

Benchmark #1: pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --no-use-pep517
  Time (mean ± σ):      2.036 s ±  0.213 s    [User: 1.763 s, System: 0.216 s]
  Range (min … max):    1.871 s …  2.529 s    10 runs
 
Benchmark #2: pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --use-pep517
  Time (mean ± σ):      6.877 s ±  0.267 s    [User: 6.134 s, System: 0.658 s]
  Range (min … max):    6.458 s …  7.327 s    10 runs
 
Summary
  'pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --no-use-pep517' ran
    3.38 ± 0.38 times faster than 'pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --use-pep517'

I know it is a small project so this might be an extreme case, but this appears to be unexpected.

Code of Conduct

@zmanji zmanji added S: needs triage Issues/PRs that need to be triaged type: bug A confirmed bug or unintended behavior labels Jun 13, 2021
@pfmoore
Copy link
Member

pfmoore commented Jun 13, 2021

This is probably caused by build isolation (which is used in PEP 517 builds but not in the "legacy" code path, if I remember correctly). Does performance improve if you use --no-build-isolation?

(Please understand that I'm asking for diagnosis purposes - you most definitely should not recommend using --no-build-isolation simply as a way of speeding up builds).

@zmanji
Copy link
Author

zmanji commented Jun 13, 2021

Adding --no-build-isolation closes the gap:

Benchmark #1: pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --no-use-pep517
  Time (mean ± σ):      1.622 s ±  0.086 s    [User: 1.170 s, System: 0.331 s]
  Range (min … max):    1.522 s …  1.776 s    10 runs
 
Benchmark #2: pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --use-pep517 --no-build-isolation
  Time (mean ± σ):      1.620 s ±  0.049 s    [User: 1.166 s, System: 0.325 s]
  Range (min … max):    1.546 s …  1.702 s    10 runs
 
Summary
  'pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --use-pep517 --no-build-isolation' ran
    1.00 ± 0.06 times faster than 'pip wheel --use-feature=in-tree-build -w dist/ --only-binary ":all:" --no-deps -r requirements.txt . --no-use-pep517'

Is this expected?

@pfmoore
Copy link
Member

pfmoore commented Jun 13, 2021

Yes. When building using PEP 517/518, the build requirements (which are usually specified in pyproject.toml, but which will default to setuptools' "legacy" backend if not specified) may not be installed in the user's current environment. So pip installs them into a virtual environment and builds with that - that obviously takes some extra time. --no-build-isolation skips that virtual environment build step, but the cost is that the build will fail if you don't have all of the necessary dependencies installed (and in extreme cases that may not even be possible, if two requirements depend on, for example, different versions of setuptools to build).

While it would be nice to avoid the cost of setting up a build environment when it's not needed, it's frankly not been a significant issue for anyone until this point, and it would be hard to do so reliably. The legacy build process did none of this - it just tried the build in the environment the project was being installed into, and if that failed, tough. Of course, for simpler projects like your example, this worked fine. But for more complex projects it was an issue.

@pradyunsg
Copy link
Member

pradyunsg commented Jun 13, 2021

And we do want to improve in this area -- there's other issues tracking that (like #7294).

@edmorley
Copy link
Contributor

@zmanji Does #11257 (in pip 22.2) make much of a difference to the benchmark results?

sfoster1 added a commit to Opentrons/oe-core that referenced this issue Oct 2, 2023
A recent pip/setuptools update made pep517 isolated builds the default. That's really good and I would like to use it but also it makes the builds incredibly slow: pypa/pip#10060 We need to keep pep517 because it's what allows pyproject tomls to specify build deps, but by preinstalling those build deps and turning off build isolation we can make it fast again. This isn't a good general purpose solution and it will surely break at some point when we add some new package but we can cross that bridge when we come to it
@ichard26 ichard26 added resolution: not a bug Determined as not a bug in pip and removed S: needs triage Issues/PRs that need to be triaged labels Jun 23, 2024
@ichard26
Copy link
Member

As discussed earlier, this is expected behaviour. I'm going to close this as #9081 and #7294 are already tracking potential avenues to reduce the build environment provisioning overhead.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
resolution: not a bug Determined as not a bug in pip type: bug A confirmed bug or unintended behavior
Projects
None yet
Development

No branches or pull requests

5 participants