17 Punkte von GN⁺ 2025-12-27 | Noch keine Kommentare. | Auf WhatsApp teilen
  • Der Python-Paketmanager uv erreicht eine mehr als 10-mal schnellere Installationsgeschwindigkeit als pip. Das liegt nicht einfach daran, dass er in Rust geschrieben ist, sondern an bewussten Designentscheidungen
  • Der Schlüssel zur Geschwindigkeit sind Standards für statische Metadaten (PEP 518, 517, 621, 658), die es ermöglichen, Abhängigkeiten ohne Codeausführung zu ermitteln
  • uv entfernt konsequent Legacy-Funktionen, die pip weiter mitträgt (.egg, pip.conf, System-Python-Installationen usw.), und beseitigt so unnötige Codepfade
  • Rust trägt mit Zero-Copy-Deserialisierung, lockfreier Nebenläufigkeit und einer Single-Binary-Struktur bei, macht aber nur einen Teil der gesamten Geschwindigkeitssteigerung aus
  • Insgesamt zeigt das Beispiel uv, dass standardisierte Metadaten und das Entfernen unnötiger Kompatibilität der Schlüssel zu Performance-Innovationen sind

Die Standards hinter der Geschwindigkeit von uv

  • Die Langsamkeit von pip ist kein Implementierungsproblem, sondern Folge der früheren setup.py-basierten Struktur, bei der zur Ermittlung von Abhängigkeiten Code ausgeführt werden musste
    • Für die Ausführung von setup.py mussten Build-Abhängigkeiten installiert werden, was zu einem „Henne-Ei-Problem“ führte
    • Während der Installation kam es zu beliebiger Codeausführung und wiederholten Fehlschlägen, was die Installationsgeschwindigkeit verringerte
  • PEP 518 (2016) führte pyproject.toml ein, sodass Build-Abhängigkeiten ohne Codeausführung deklariert werden können
  • PEP 517 (2017) trennte Build-Frontend und Backend, sodass pip die Interna von setuptools nicht mehr verstehen muss
  • PEP 621 (2020) standardisierte die Tabelle [project], sodass sich Abhängigkeiten allein durch TOML-Parsing prüfen lassen
  • PEP 658 (2022) bindet Paketmetadaten direkt in die Simple Repository API ein, sodass sich Abhängigkeitsinformationen ohne Download eines Wheels abrufen lassen
  • PyPI führte PEP 658 im Mai 2023 ein, und uv erschien im Februar 2024 als erstes Tool, das die neue Standard-Infrastruktur vollständig nutzt
  • Wie bei Rusts Cargo oder npm stellt nun auch das Python-Ökosystem auf Packaging auf Basis statischer Metadaten um

Welche Funktionen uv entfernt hat

  • Die Geschwindigkeit von uv entsteht durch das Entfernen unnötiger Funktionen
    • Keine .egg-Unterstützung: pip verarbeitet sie weiterhin, uv schließt sie vollständig aus
    • pip.conf wird ignoriert: Konfigurationsdateien, Umgebungsvariablen und Vererbungslogik werden komplett ausgelassen
    • Bytecode-Kompilierung deaktiviert: .py wird nicht in .pyc umgewandelt, was die Installationszeit verkürzt
    • Virtuelle Umgebungen sind Pflicht: direkte Installationen in das System-Python entfallen, wodurch Berechtigungsprüfungen und Sicherheitscode wegfallen
    • Strikte Spezifikationskonformität: fehlerhafte Pakete werden abgelehnt, wodurch Ausnahmelogik kleiner wird
    • Obergrenzen bei requires-python werden ignoriert: defensive Einschränkungen wie python<4.0 werden ignoriert, was weniger Abhängigkeitsauflösung per Backtracking bedeutet
    • Der erste Index hat Vorrang: Wird ein Paket im ersten von mehreren Indizes gefunden, stoppt uv sofort, was Dependency-Confusion-Angriffe verhindert und Netzwerkanfragen reduziert
  • All diese Punkte zeigen, welche Codepfade pip ausführen muss und uv eliminiert

Optimierungen, die auch ohne Rust möglich sind

  • Ein großer Teil der Geschwindigkeit von uv kommt von designbezogenen Optimierungen, die nicht an die Sprache gebunden sind
    • Mit HTTP-Range-Requests wird nur das zentrale Verzeichnis einer Wheel-Datei teilweise heruntergeladen, statt die gesamte Datei zu laden
    • Parallele Downloads holen mehrere Pakete gleichzeitig
    • Ein globaler Cache und Hardlinks sorgen dafür, dass die Installation desselben Pakets in mehreren virtuellen Umgebungen keinen zusätzlichen Speicherplatz verbraucht
    • Python-unabhängige Auflösung: TOML- und Wheel-Metadaten werden direkt geparst, und Python wird nur ausgeführt, wenn es ausschließlich setup.py gibt
    • Die Verwendung des PubGrub-Algorithmus zur Abhängigkeitsauflösung ist schneller als pips Backtracking-Ansatz und liefert klarere Fehlermeldungen

Was Rust tatsächlich beigetragen hat

  • Rust spielt bei bestimmten Low-Level-Optimierungen eine wichtige Rolle
    • Zero-Copy-Deserialisierung auf Basis von rkyv ermöglicht die direkte Nutzung von Cache-Daten ohne Kopieren
    • Lockfreie Nebenläufigkeitsstrukturen ermöglichen sicheren parallelen Zugriff
    • Keine Interpreter-Initialisierung: uv ist ein einzelnes statisches Binary und vermeidet die Kosten für das Starten von Python-Prozessen bei pip
    • Versionsinformationen werden als u64-Integer komprimiert dargestellt, wodurch Vergleiche und Hash-Operationen schneller werden
  • Diese Elemente steigern die Performance, sind aber nicht die Hauptursache für den gesamten Geschwindigkeitsgewinn

Die wichtigste Lehre

  • Die Geschwindigkeit von uv kommt nicht von Rust, sondern von den Dingen, die es nicht tut
  • Die Standardisierung durch PEP 518, 517, 621 und 658 hat die Grundlage für schnelle Paketverwaltung geschaffen, und uv setzt das mit Legacy-Abbau und modernen Annahmen um
  • Auch pip könnte parallele Downloads, einen globalen Cache und metadatenbasierte Auflösung implementieren, aber 15 Jahre Abwärtskompatibilität sind ein Hindernis
  • Deshalb kann pip letztlich nur langsam bleiben, und nur Werkzeuge, die von neuen Prämissen ausgehen, können grundlegende Geschwindigkeitsgewinne erreichen
  • Die Lehre für andere Paketmanager lautet, dass statische Metadaten, Abhängigkeitsermittlung ohne Codeausführung und vorab auflösbare Strukturen unverzichtbar sind
  • Cargo und npm nutzen diesen Ansatz bereits, und Ökosysteme, die zur Prüfung von Abhängigkeiten Code ausführen müssen, sind grundsätzlich langsam

Noch keine Kommentare.

Noch keine Kommentare.