Pythonのパッケージマネージャ「uv」を試してみたら爆速だった

## はじめに
最近登場したPythonのパッケージマネージャである`uv`を試してみました。
単純に試してみたかったのと、仕事で開発しているプロダクトのCI/CDが遅く、その中のPythonの仮想環境の構築に時間がかかっていたので、それを改善できないかと思ったからです。
この記事ではそこまではいかず、ひとまず適当なライブラリで仮想環境を作って速度を試して見たいと思います。

https://github.com/astral-sh/uv

## 前提
* Ubuntu-22.04 (WSL2)
* Python 3.12.1
* uv 0.1.10

## 検証のため用意したrequirements.txt

これを通常のpipでのインストールとuvでのインストールで速度を比較してみたいと思います。

```requirements.txt
fastapi==0.109.2
alembic==1.13.1
SQLAlchemy==2.0.27
pandas==2.2.1
pydantic==2.6.2
click==8.1.7
requests==2.31.0
numpy==1.26.4
matplotlib
boto3==1.34.49
pytest==8.0.1
pytest-cov==4.1.0
mypy==1.8.0
ruff==0.2.2
```


## 通常のpip

### キャッシュの削除
まずはpipのキャッシュを削除しておきます。
```bash
rm -rf ~/.cache/pip
```

### 仮装環境の作成とactivate
```bash
❯ time python -m venv .venv_normal_pip

real    0m1.963s
user    0m1.814s
sys     0m0.109s
```

```bash
source .venv_normal_pip/bin/activate
```

### requirements.txtからインストール

```bash
❯ time pip install -r requirements.txt
Collecting fastapi==0.109.2 (from -r requirements.txt (line 1))
  Obtaining dependency information for fastapi==0.109.2 from https://files.pythonhosted.org/packages/bf/97/60351307ab4502908d29f64f2801a36709a3f1888447bb328bc373d6ca0e/fastapi-0.109.2-py3-none-any.whl.metadata
  Downloading fastapi-0.109.2-py3-none-any.whl.metadata (25 kB)
Collecting alembic==1.13.1 (from -r requirements.txt (line 2))
  Obtaining dependency information for alembic==1.13.1 from https://files.pythonhosted.org/packages/7f/50/9fb3a5c80df6eb6516693270621676980acd6d5a9a7efdbfa273f8d616c7/alembic-1.13.1-py3-none-any.whl.metadata

...(中略)...

Downloading coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (238 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 238.9/238.9 kB 16.0 MB/s eta 0:00:00
Downloading sniffio-1.3.0-py3-none-any.whl (10 kB)
Installing collected packages: pytz, urllib3, tzdata, typing-extensions, sniffio, six, ruff, pyparsing, pluggy, pillow, packaging, numpy, mypy-extensions, MarkupSafe, kiwisolver, jmespath, iniconfig, idna, greenlet, fonttools, cycler, coverage, click, charset-normalizer, certifi, annotated-types, SQLAlchemy, requests, python-dateutil, pytest, pydantic-core, mypy, Mako, contourpy, anyio, starlette, pytest-cov, pydantic, pandas, matplotlib, botocore, alembic, s3transfer, fastapi, boto3
Successfully installed Mako-1.3.2 MarkupSafe-2.1.5 SQLAlchemy-2.0.27 alembic-1.13.1 annotated-types-0.6.0 anyio-4.3.0 boto3-1.34.49 botocore-1.34.49 certifi-2024.2.2 charset-normalizer-3.3.2 click-8.1.7 contourpy-1.2.0 coverage-7.4.3 cycler-0.12.1 fastapi-0.109.2 fonttools-4.49.0 greenlet-3.0.3 idna-3.6 iniconfig-2.0.0 jmespath-1.0.1 kiwisolver-1.4.5 matplotlib-3.8.3 mypy-1.8.0 mypy-extensions-1.0.0 numpy-1.26.4 packaging-23.2 pandas-2.2.1 pillow-10.2.0 pluggy-1.4.0 pydantic-2.6.2 pydantic-core-2.16.3 pyparsing-3.1.1 pytest-8.0.1 pytest-cov-4.1.0 python-dateutil-2.8.2 pytz-2024.1 requests-2.31.0 ruff-0.2.2 s3transfer-0.10.0 six-1.16.0 sniffio-1.3.0 starlette-0.36.3 typing-extensions-4.9.0 tzdata-2024.1 urllib3-2.0.7

[notice] A new release of pip is available: 23.2.1 -> 24.0
[notice] To update, run: pip install --upgrade pip

real    0m25.809s
user    0m15.631s
sys     0m1.605s
```

最後にdeactivateしておきます。
```bash
deactivate
```


## uv

### uvのインストール
普段Ryeを使っていたので、Ryeの中のuvを有効化して使うことも試してみたのですが、うまくいかなかったので単体でインストールしました。

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

### キャッシュの削除
uvの方もキャッシュを削除しておきます。
```bash
uv cache clean
```

### 仮想環境の作成とactivate
```bash
time uv venv
Using Python 3.12.1 interpreter at /home/mottyzzz/pythons/python3
Creating virtualenv at: .venv
Activate with: source .venv/bin/activate

real    0m0.169s
user    0m0.007s
sys     0m0.156s
```
コマンド実行した瞬間に終わって、エッってなりました。この時点でもはや感動。


### requirements.txtからインストール

```bash
❯ time uv pip install -r requirements.txt
Resolved 45 packages in 827ms
Downloaded 45 packages in 6.85s
Installed 45 packages in 75ms
 + alembic==1.13.1
 + annotated-types==0.6.0
 + anyio==4.3.0
 + boto3==1.34.49
 + botocore==1.34.49
 + certifi==2024.2.2

...(中略)...

 + s3transfer==0.10.0
 + six==1.16.0
 + sniffio==1.3.0
 + sqlalchemy==2.0.27
 + starlette==0.36.3
 + typing-extensions==4.9.0
 + tzdata==2024.1
 + urllib3==2.0.7

real    0m7.798s
user    0m1.873s
sys     0m1.881s
```

はやーい。
ほぼダウンロードの時間だけですね。

## まとめ
最後に結果を表でまとめます。

メインの`requirements.txt`からのインストールでは、uvの方が3倍くらい速い結果となりました。実際の業務で使うためにはもう少し様子を見るかもしれませんが、CI/CDの速度向上に向けて大きな期待感が出てきました。

| 項目 | 通常のpip | uv |
|---|--:|--:|
| 仮想環境の作成 | 1.963 秒 | 0.169 秒 |
| `requirements.txt`からのインストール | 25.809 秒  | 7.798 秒 |