17 ポイント 投稿者 GN⁺ 2025-12-27 | 1件のコメント | WhatsAppで共有
  • Pythonパッケージマネージャー uv は、pipより 10倍以上速いインストール速度 を示しており、これは単にRustで書かれているからではなく、設計上の選択 によるもの
  • 速度を実現した中核は 静的メタデータ標準(PEP 518, 517, 621, 658) で、コードを実行せずに依存関係を把握できるようにしたこと
  • uvはpipが維持している レガシー機能(.egg、pip.conf、システムPythonへのインストールなど) を大胆に削り、不要なコードパスを排除 した
  • Rustが寄与した部分は ゼロコピー逆シリアライズ、ロックフリー並行性、単一バイナリ構成 などで、全体の高速化のうち一部にすぎない
  • 全体としてuvの事例は、標準化されたメタデータと不要な互換性の除去こそが性能革新の核心 であることを示している

uvの速度を可能にした標準

  • pipが遅いのは実装の問題ではなく、過去の setup.pyベースの構造 により、依存関係を知るためにコードを実行しなければならなかったため
    • setup.pyの実行にはビルド依存関係のインストールが必要で、これは 「鶏と卵の問題」 を引き起こした
    • インストール過程で 任意コードの実行と繰り返される失敗 が発生し、インストール速度を低下させた
  • PEP 518(2016)pyproject.toml を導入し、コード実行なしでビルド依存関係を宣言できるようにした
  • PEP 517(2017) はビルドフロントエンドとバックエンドを分離し、pipがsetuptoolsの内部を理解する必要をなくした
  • PEP 621(2020)[project] テーブルを標準化し、TOMLを解析するだけで依存関係を確認できるようにした
  • PEP 658(2022) はパッケージメタデータを Simple Repository API に直接含め、wheelをダウンロードせずに依存関係情報を取得できるようにした
  • PyPIは2023年5月にPEP 658を適用し、uvは2024年2月に公開され、新しい標準インフラを完全活用した最初のツール として登場した
  • RustのCargoやnpmのように、Pythonエコシステムも今や 静的メタデータベースのパッケージング へ移行している

uvが削除した機能

  • uvの速さは 不要な機能の削減 から生まれている
    • .eggのサポートなし: pipは今も処理するが、uvは完全に除外
    • pip.confを無視: 設定ファイル、環境変数、継承ロジックをすべて省略
    • バイトコードコンパイルを無効化: .py.pyc に変換せず、インストール時間を短縮
    • 仮想環境を必須化: システムPythonへ直接インストールしないため、権限チェックや安全性コードを削除
    • 厳格な仕様準拠: 不正なパッケージを拒否し、例外処理ロジックを縮小
    • requires-pythonの上限制約を無視: python<4.0 のような防御的制約を無視し、依存関係解決(バックトラッキング) を削減
    • 最初のインデックスを優先: 複数のインデックスのうち最初でパッケージを見つけたら即座に停止し、依存関係混同攻撃の防止とネットワークリクエスト削減 を実現
  • これらはすべて、pipが通る必要のあるコードパスをuvが削除した例である

Rustなしでも可能な最適化

  • uvの高速化のかなりの部分は 言語に依存しない設計最適化 に由来する
    • HTTP Rangeリクエスト でwheelファイルのセントラルディレクトリだけを部分ダウンロードし、全体のダウンロードを回避
    • 並列ダウンロード により複数パッケージを同時に取得
    • グローバルキャッシュとハードリンク を使い、同一パッケージを複数の仮想環境にインストールしても 追加のディスク容量を消費しない
    • Python非依存の解析: TOMLとwheelメタデータを直接解析し、setup.pyしかない場合にのみPythonを実行
    • PubGrub依存関係解決アルゴリズム を採用し、pipのバックトラッキング方式より高速で、エラー説明も明確

Rustが実際に寄与した部分

  • Rustは特定の 低レベル最適化 において重要な役割を果たしている
    • rkyvベースのゼロコピー逆シリアライズ により、キャッシュデータをコピーせず直接利用
    • ロックフリーの並行データ構造 により、安全な並列アクセスを実装
    • インタプリタ初期化が不要: uvは単一の静的バイナリであり、pipのPythonプロセス起動コストを排除
    • バージョン情報をu64整数に圧縮表現 し、比較やハッシュ計算を高速化
  • これらの要素は性能を高めるが、全体の高速化の主因ではない

重要な教訓

  • uvの速さは Rustだからではなく、やらないことが多いから 生まれている
  • PEP 518・517・621・658の標準化が 高速なパッケージ管理の基盤 を整え、uvは レガシー排除と現代的な前提 によってそれを実現した
  • pipも並列ダウンロード、グローバルキャッシュ、メタデータベースの解析を実装できるが、15年にわたる下位互換性の維持 が障害になっている
  • 結果としてpipは常に遅くならざるを得ず、新しい前提から出発したツールだけが根本的な高速化を実現できる
  • 他のパッケージマネージャーへの教訓は、静的メタデータ・コード実行なしの依存関係探索・事前解決可能な構造 が不可欠だという点
  • Cargoとnpmはすでにこの方式を採用しており、依存関係確認のためにコードを実行しなければならないエコシステムは本質的に遅い

1件のコメント

 
GN⁺ 2025-12-27
Hacker Newsの反応
  • この記事は uvの性能 を多角的にうまく説明していると思う
    Rustで書かれている点も助けにはなっているが、この10年間でPythonエコシステムが setup.py 依存から脱却するよう進めてきた 標準化の取り組み のほうが、はるかに大きな役割を果たした

    • 以前Haskellのプロジェクトを進めていたとき、言語そのものよりも 専門性の高いコミュニティ を選別できることが利点だった
      Rustも同じように、コミュニティの力量を引き上げる理由で選ぶ価値がある
    • 多くのRustへのリライトプロジェクトは、こうした 後光効果 を得ている
      既存の試行錯誤をたどり直しながらよりよい設計ができ、そこにRust自体の利点も加わって、いわば「ワンツーパンチ」になっている
  • 「uvはRustだから速いのではなく、やっていないこと が多いから速い」という主張には共感する
    ただし、ベンチマークなしで速度要因を断定するのは早いとも思う
    PEP 518, 517, 621, 658 の影響は大きいが、互換性の削除 がどれだけ貢献したのかは疑問だ
    また、言語選択が最適化にどんな影響を与えたのかも扱われていない
    CargoのTOMLパーサーがPythonよりはるかに速い点も興味深い

    • pipの過去バージョンと現在バージョンを比較するのも、一種のベンチマークになりうる
      実際にはTOMLはビルド時にしか読まれないので比重は大きくないが、wheelの普及 が速度向上に貢献した
      関連参考記事: setup.py deprecated, wheels are faster
  • rkyv を使った zero-copy deserialization はRust固有の技術ではない
    C/C++ のような低水準言語でも可能だ

    • ここで「Rust専用」と言っていたのは、「Pythonでは不可能だ」という意味だと理解した
      「インタプリタの起動がない」というのも同じ文脈だ
    • Pythonではzero-copyを実装しにくいため、Rustがこれを 安全かつ簡単に した点は認める
    • 結局この議論はRust対Pythonの比較だ
  • 記事の内容は良いが、LLMが整えた文体 があまりに人工的に感じられる
    いつかはLLMによって壊れた文章を、再び人間らしく復元する時代が来るのかもしれない

    • 筆者はSBOMとLockfile関連の記事でもHNに載ったことがある
      サプライチェーンセキュリティの専門家に見えるが、その記事もLLM特有の 曖昧な文体 に変質していた印象だった
    • 逆に、ある人はLLMっぽさをまったく感じず、自然だと思った
    • 自分はもう、文章から AI臭さ を感じたらすぐ閉じる
      固定化したプロンプトがどの文章も似たものにしてしまい、インターネット全体が同じ声で話しているように聞こえるのが残念だ
  • uvの速さに熱狂する空気が理解できない
    たいていのPythonユーザーは、パッケージのインストール速度を 悩みの上位10項目 にすら入れていない気がする
    自分も毎日Pythonを使っているが、体感はそこまで大きくない

    • 前の会社では poetry で依存関係の更新に5〜30分かかっていた
      失敗したらまた30分待たなければならず、uvは本当に 快適な体験 だった
    • 20年以上Pythonを使ってきたが、pip install がデプロイ時間の大きな割合を占めていた
      キャッシュで速度を上げようと苦労した時間が多かった
    • 自分の業務用モノリシックアプリでは poetry install は2分、uv sync は数秒で終わる
      CIごとに2分節約できるので、積み重ね効果が大きい
    • uvx sometool を実行するときも、仮想環境の作成と依存関係のインストール が数秒で終わるので、作業フローが完全に変わる
    • 長年のPythonユーザーとして、uvの速さは「生活の質が変わる」レベルだ
      もうuvのないプロジェクトには戻りにくい
  • uvの一部の 速度最適化手法 はpipにも移植できそうに見える
    例: 並列ダウンロード、.pyc の遅延生成、eggの無視、バージョンチェックなど
    ただ、uvはvenvの扱いがあまりにうまいので、わざわざpipをいじる必要はなさそうだ
    結局のところ「Rustのおかげだけではない」という点では、pipにもまだ速くなる余地はある

  • 速い言語を選ぶプログラマは、すでに 性能最適化のマインドセット を持っていることが多い
    言語そのものより、そうした姿勢のほうが性能を左右する

  • uvが python<4.0 の上限制約を無視する理由が興味深い
    大半のパッケージはPython 4で壊れることを恐れて 防御的に 設定しているだけで、実際には問題ない
    上限制約は現実的な問題よりも、仮想的な問題を解決しようとする試みだった

    • uvがすべての上限制約を無視しているわけではなく、4.0限定 で無視しているようだ
      python<3.0 のような制約は依然として重要なので、そのようなケースは防ぐべきだ
  • PEP 658が2023年に適用され、uvが2024年に登場したのは偶然ではない
    エコシステムの準備が整ったからこそ、uvのようなツールが可能になった
    ただ、パッケージメンテナーたちがなぜこうした変化を受け入れたのかは気になる
    setup.py でうまく回っていた人たちもいたはずだが、pyproject.toml へ移行した動機は何だったのだろうか

    • 実際のところ、setup.py は多くの人にとって不便だった
      たとえばRequestsですら、まだ完全なPEP 517/518/621互換ではない
      1年半たってもマイナーリリースが遅れており、その間に ビルド問題 も発生していた
    • 静的宣言のほうが 安全で性能上も有利 だったからだ
      ただし、pipがなぜこれを十分に活用していないのかは疑問だ
  • 「実行しないコードパスは待つ必要がない」という表現は不正確だ
    時間を節約するのは、実際に実行しないコードだけだ
    たとえば .egg サポートがなくても、それがすでに 廃止された形式 なら速度には影響しない
    実際にどの項目がどれだけ時間を節約したのかという 定量データ があれば、さらに良かったと思う
    それでも全体としてはよく整理された記事だ