Skip to content

Commit 25d3d98

Browse files
authored
Merge pull request #6419 from pypa/increase-resolution-depth
Performance Optimization: Resolver, Benchmarking & Batch Operations
2 parents 621fafa + 959ab65 commit 25d3d98

File tree

19 files changed

+900
-95
lines changed

19 files changed

+900
-95
lines changed

.github/workflows/ci.yaml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,36 @@ jobs:
139139
run: |
140140
pipenv run pytest -ra -n auto -v --fulltrace tests
141141
142+
benchmark:
143+
name: Package Manager Benchmark
144+
needs: lint
145+
runs-on: ubuntu-latest
146+
steps:
147+
- uses: actions/checkout@v4
148+
- uses: actions/setup-python@v5
149+
with:
150+
python-version: "3.11"
151+
- name: Install system dependencies
152+
run: |
153+
sudo apt-get update -qq
154+
sudo apt-get install -y libxmlsec1-dev librdkafka-dev
155+
- name: Install benchmark utilities
156+
run: pip install csv2md
157+
- name: Run benchmark suite
158+
working-directory: benchmarks
159+
run: python benchmark.py
160+
- name: Display benchmark results
161+
working-directory: benchmarks
162+
run: |
163+
if [ -f stats.csv ]; then
164+
csv2md stats.csv >> $GITHUB_STEP_SUMMARY
165+
fi
166+
- uses: actions/upload-artifact@v4
167+
with:
168+
name: pipenv-benchmark-stats
169+
path: benchmarks/stats.csv
170+
retention-days: 30
171+
142172
build:
143173
name: Build Package
144174
needs: lint

Makefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,3 +180,12 @@ reimport-pip-patch:
180180
pypi-server: SERVER ?= gunicorn
181181
pypi-server:
182182
pipenv run pypi-server run --server $(SERVER) -v --host=0.0.0.0 --port=8080 --hash-algo=sha256 --disable-fallback ./tests/pypi/ ./tests/fixtures
183+
184+
.PHONY: benchmark
185+
benchmark:
186+
cd benchmarks && python benchmark.py
187+
188+
.PHONY: benchmark-clean
189+
benchmark-clean:
190+
cd benchmarks && rm -f requirements.txt Pipfile.lock stats.csv
191+
cd benchmarks && rm -rf timings/

benchmarks/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Generated files
2+
requirements.txt
3+
Pipfile.lock
4+
stats.csv
5+
6+
# Timing data
7+
timings/
8+
9+
# Virtual environments
10+
.venv/
11+
__pycache__/

benchmarks/Pipfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[[source]]
2+
url = "https://pypi.org/simple"
3+
verify_ssl = true
4+
name = "pypi"
5+
6+
[packages]
7+
# Dependencies will be added during benchmark import step
8+
9+
[dev-packages]
10+
11+
[requires]
12+
python_version = "3.11"

benchmarks/README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Pipenv Package Manager Benchmark
2+
3+
This directory contains benchmarking tests for pipenv based on the [python-package-manager-shootout](https://github.com/lincolnloop/python-package-manager-shootout) project.
4+
5+
## Purpose
6+
7+
These benchmarks help validate that pipenv performance doesn't regress over time by testing common package management operations against a real-world dependency set from [Sentry's requirements](https://github.com/getsentry/sentry/blob/main/requirements-base.txt).
8+
9+
## Operations Benchmarked
10+
11+
- **tooling** - Installing pipenv using the current development version
12+
- **import** - Converting requirements.txt to Pipfile format
13+
- **lock** - Generating Pipfile.lock from dependencies
14+
- **install-cold** - Installing packages with empty cache
15+
- **install-warm** - Installing packages with populated cache
16+
- **update** - Updating all packages to latest versions
17+
- **add-package** - Adding a new package and updating lock file
18+
19+
## Usage
20+
21+
### Local Testing
22+
23+
```bash
24+
# Run all benchmark operations
25+
make benchmark
26+
27+
# Clean benchmark artifacts
28+
make benchmark-clean
29+
30+
# Run individual operations
31+
cd benchmarks
32+
python benchmark.py # Run full benchmark suite
33+
python benchmark.py setup # Download requirements.txt
34+
python benchmark.py tooling # Benchmark pipenv installation
35+
python benchmark.py import # Benchmark requirements import
36+
python benchmark.py lock-cold # Benchmark lock with cold cache
37+
python benchmark.py lock-warm # Benchmark lock with warm cache
38+
python benchmark.py install-cold # Benchmark install with cold cache
39+
python benchmark.py install-warm # Benchmark install with warm cache
40+
python benchmark.py update-cold # Benchmark update with cold cache
41+
python benchmark.py update-warm # Benchmark update with warm cache
42+
python benchmark.py add-package # Benchmark adding a package
43+
python benchmark.py stats # Generate stats.csv
44+
```
45+
46+
### CI Integration
47+
48+
The benchmarks run automatically in GitHub Actions on the `ubuntu-latest` runner as part of the CI pipeline. Results are:
49+
50+
- Displayed in the job summary with timing statistics
51+
- Uploaded as artifacts for historical analysis
52+
- Used to detect performance regressions
53+
54+
## Files
55+
56+
- `benchmark.py` - Main benchmark runner script
57+
- `Pipfile` - Base Pipfile template (dependencies added during import)
58+
- `requirements.txt` - Downloaded from Sentry's requirements-base.txt during setup
59+
- `timings/` - Directory created during benchmarks to store timing data
60+
- `stats.csv` - Generated CSV with benchmark results
61+
62+
## Dependencies
63+
64+
The benchmark uses Sentry's `requirements-base.txt` as a representative real-world dependency set. This includes packages like:
65+
66+
- Django and related packages
67+
- Database connectors
68+
- Serialization libraries
69+
- HTTP clients
70+
- Development tools
71+
72+
## Notes
73+
74+
- Benchmarks only run on Linux in CI to ensure consistent timing measurements
75+
- System dependencies (libxmlsec1-dev, librdkafka-dev) are installed for Sentry requirements
76+
- Cache clearing ensures cold/warm scenarios are properly tested
77+
- Results include CPU time, memory usage, and I/O statistics

0 commit comments

Comments
 (0)