63f7f65190
This copies the allocator configuration used in the Ruff project. In
particular, this gives us an instant 10% win when resolving the top 1K
PyPI packages:
$ hyperfine \
"./target/profiling/puffin-dev-main resolve-many --cache-dir
cache-docker-no-build --no-build pypi_top_8k_flat.txt --limit 1000 2>
/dev/null" \
"./target/profiling/puffin-dev resolve-many --cache-dir
cache-docker-no-build --no-build pypi_top_8k_flat.txt --limit 1000 2>
/dev/null"
Benchmark 1: ./target/profiling/puffin-dev-main resolve-many --cache-dir
cache-docker-no-build --no-build pypi_top_8k_flat.txt --limit 1000 2>
/dev/null
Time (mean ± σ): 974.2 ms ± 26.4 ms [User: 17503.3 ms, System: 2205.3
ms]
Range (min … max): 943.5 ms … 1015.9 ms 10 runs
Benchmark 2: ./target/profiling/puffin-dev resolve-many --cache-dir
cache-docker-no-build --no-build pypi_top_8k_flat.txt --limit 1000 2>
/dev/null
Time (mean ± σ): 883.1 ms ± 23.3 ms [User: 14626.1 ms, System: 2542.2
ms]
Range (min … max): 849.5 ms … 916.9 ms 10 runs
Summary
'./target/profiling/puffin-dev resolve-many --cache-dir
cache-docker-no-build --no-build pypi_top_8k_flat.txt --limit 1000 2>
/dev/null' ran
1.10 ± 0.04 times faster than './target/profiling/puffin-dev-main
resolve-many --cache-dir cache-docker-no-build --no-build
pypi_top_8k_flat.txt --limit 1000 2> /dev/null'
I was moved to do this because I noticed `malloc`/`free` taking up a
fairly sizeable percentage of time during light profiling.
As is becoming a pattern, it will be easier to review this
commit-by-commit.
Ref #396 (wouldn't call this issue fixed)
-----
I did also try adding a `smallvec` optimization to the
`Version::release` field, but it didn't bare any fruit. I still think
there is more to explore since the results I observed don't quite line
up with what I expect. (So probably either my mental model is off or my
measurement process is flawed.) You can see that attempt with a little
more explanation here:
https://github.com/astral-sh/puffin/commit/f9528b4ecd1b0c260df7e8ad57b9ddc4da09d273
In the course of adding the `smallvec` optimization, I also shrunk the
`Version` fields from a `usize` to a `u32`. They should at least be a
fixed size integer since version numbers aren't used to index memory,
and I shrunk it to `u32` since it seems reasonable to assume that all
version numbers will be smaller than `2^32`.
77 lines
2.5 KiB
TOML
77 lines
2.5 KiB
TOML
[package]
|
|
name = "puffin-cli"
|
|
version = "0.0.1"
|
|
edition = { workspace = true }
|
|
rust-version = { workspace = true }
|
|
homepage = { workspace = true }
|
|
documentation = { workspace = true }
|
|
repository = { workspace = true }
|
|
authors = { workspace = true }
|
|
license = { workspace = true }
|
|
|
|
[[bin]]
|
|
name = "puffin"
|
|
path = "src/main.rs"
|
|
|
|
[dependencies]
|
|
gourgeist = { path = "../gourgeist" }
|
|
install-wheel-rs = { path = "../install-wheel-rs", default-features = false }
|
|
pep440_rs = { path = "../pep440-rs" }
|
|
pep508_rs = { path = "../pep508-rs" }
|
|
platform-host = { path = "../platform-host" }
|
|
platform-tags = { path = "../platform-tags" }
|
|
pubgrub = { path = "../../vendor/pubgrub" }
|
|
puffin-client = { path = "../puffin-client" }
|
|
puffin-dispatch = { path = "../puffin-dispatch" }
|
|
puffin-distribution = { path = "../puffin-distribution" }
|
|
puffin-installer = { path = "../puffin-installer" }
|
|
puffin-interpreter = { path = "../puffin-interpreter" }
|
|
puffin-normalize = { path = "../puffin-normalize" }
|
|
pypi-types = { path = "../pypi-types" }
|
|
requirements-txt = { path = "../requirements-txt" }
|
|
puffin-resolver = { path = "../puffin-resolver", features = ["clap"] }
|
|
puffin-workspace = { path = "../puffin-workspace" }
|
|
|
|
anyhow = { workspace = true }
|
|
bitflags = { workspace = true }
|
|
cacache = { workspace = true }
|
|
clap = { workspace = true, features = ["derive"] }
|
|
colored = { workspace = true }
|
|
directories = { workspace = true }
|
|
fs-err = { workspace = true, features = ["tokio"] }
|
|
futures = { workspace = true }
|
|
indicatif = { workspace = true }
|
|
itertools = { workspace = true }
|
|
miette = { workspace = true, features = ["fancy"] }
|
|
pyproject-toml = { workspace = true }
|
|
tempfile = { workspace = true }
|
|
thiserror = { workspace = true }
|
|
tokio = { workspace = true }
|
|
toml = { workspace = true }
|
|
tracing = { workspace = true }
|
|
tracing-subscriber = { workspace = true }
|
|
tracing-tree = { workspace = true }
|
|
url = { workspace = true }
|
|
which = { workspace = true }
|
|
|
|
[target.'cfg(target_os = "windows")'.dependencies]
|
|
mimalloc = "0.1.39"
|
|
|
|
[target.'cfg(all(not(target_os = "windows"), not(target_os = "openbsd"), any(target_arch = "x86_64", target_arch = "aarch64", target_arch = "powerpc64")))'.dependencies]
|
|
tikv-jemallocator = "0.5.0"
|
|
|
|
[dev-dependencies]
|
|
assert_cmd = { version = "2.0.12" }
|
|
assert_fs = { version = "1.0.13" }
|
|
insta-cmd = { version = "0.4.0" }
|
|
insta = { version = "1.34.0", features = ["filters"] }
|
|
predicates = { version = "3.0.4" }
|
|
|
|
[features]
|
|
# Introduces a dependency on a local Python installation.
|
|
python = []
|
|
# Introduces a dependency on PyPI.
|
|
pypi = []
|
|
# Introduces a dependency on Git.
|
|
git = []
|