17 पॉइंट द्वारा GN⁺ 2025-12-27 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Python package manager uv की install speed, pip की तुलना में 10 गुना से भी ज़्यादा तेज़ है। इसका कारण सिर्फ़ Rust में लिखा होना नहीं, बल्कि design से जुड़े विकल्प हैं
  • इस speed को संभव बनाने की कुंजी static metadata standards (PEP 518, 517, 621, 658) हैं, जो code चलाए बिना dependencies समझने देती हैं
  • uv, pip द्वारा बनाए रखी जाने वाली legacy features (.egg, pip.conf, system Python install आदि) को साहसपूर्वक हटाकर अनावश्यक code paths खत्म करता है
  • Rust का योगदान zero-copy deserialization, lock-free concurrency, single binary structure जैसी चीज़ों में है, लेकिन कुल speedup का सिर्फ़ एक हिस्सा वहीं से आता है
  • कुल मिलाकर, uv का उदाहरण दिखाता है कि standardized metadata और अनावश्यक compatibility हटाना ही performance innovation की कुंजी है

वे standards जिन्होंने uv की speed संभव बनाई

  • pip की धीमी रफ़्तार implementation की समस्या नहीं थी, बल्कि पुरानी setup.py आधारित संरचना की वजह से dependencies जानने के लिए code चलाना पड़ता था
    • setup.py चलाने के लिए build dependencies install करनी पड़ती थीं, जिससे "chicken-and-egg problem" पैदा होती थी
    • install process में arbitrary code execution और बार-बार failure होते थे, जिससे install speed घटती थी
  • PEP 518 (2016) ने pyproject.toml पेश किया, जिससे code चलाए बिना build dependencies declare करना संभव हुआ
  • PEP 517 (2017) ने build frontend और backend को अलग किया, जिससे pip को setuptools के अंदरूनी हिस्सों को समझने की ज़रूरत नहीं रही
  • PEP 621 (2020) ने [project] table को standardize किया, ताकि सिर्फ़ TOML parsing से dependencies जाँची जा सकें
  • PEP 658 (2022) ने package metadata को सीधे Simple Repository API में शामिल किया, जिससे wheel download किए बिना dependency information मिल सकती है
  • PyPI ने मई 2023 में PEP 658 लागू किया, और uv फ़रवरी 2024 में लॉन्च हुआ, इसलिए यह नई standard infrastructure का पूरी तरह उपयोग करने वाला पहला tool बनकर उभरा
  • Rust के Cargo या npm की तरह, Python ecosystem भी अब static metadata आधारित packaging की ओर बढ़ चुका है

वे features जिन्हें uv ने हटाया

  • uv की speed का बड़ा कारण अनावश्यक features को हटाना है
    • .egg support नहीं: pip अब भी इसे संभालता है, लेकिन uv इसे पूरी तरह बाहर रखता है
    • pip.conf को ignore करता है: config files, environment variables और inheritance logic सब हटा दिए गए हैं
    • bytecode compilation disabled: .py को .pyc में convert नहीं किया जाता, जिससे install time कम होता है
    • virtual environment अनिवार्य: system Python में direct install नहीं, इसलिए permission checks और safety code हट जाते हैं
    • strict spec compliance: गलत packages को reject करके exception handling logic कम किया गया
    • requires-python upper bounds ignore: python<4.0 जैसी defensive constraints को नज़रअंदाज़ करके dependency resolution (backtracking) कम किया जाता है
    • first index priority: कई indexes में से पहले index पर package मिलते ही रुक जाता है, जिससे dependency confusion attacks रुकते हैं और network requests घटती हैं
  • ये सभी उदाहरण दिखाते हैं कि uv ने वे code paths हटा दिए जिन्हें pip को अब भी संभालना पड़ता है

Rust के बिना भी संभव optimization

  • uv की speed का बड़ा हिस्सा language-independent design optimization से आता है
    • HTTP Range requests से wheel file की सिर्फ़ central directory आंशिक रूप से download होती है, पूरी file नहीं
    • parallel downloads से कई packages एक साथ लाए जाते हैं
    • global cache और hardlinks की मदद से एक ही package को कई virtual environments में install करने पर भी अतिरिक्त disk space नहीं लगता
    • Python-independent resolution: TOML और wheel metadata को सीधे parse किया जाता है, और Python सिर्फ़ तब चलाया जाता है जब केवल setup.py मौजूद हो
    • PubGrub dependency resolution algorithm का उपयोग pip की backtracking पद्धति से तेज़ है और error explanations भी अधिक स्पष्ट देता है

Rust का वास्तविक योगदान

  • Rust कुछ खास low-level optimizations में महत्वपूर्ण भूमिका निभाता है
    • rkyv आधारित zero-copy deserialization से cache data को copy किए बिना सीधे इस्तेमाल किया जाता है
    • lock-free concurrency structures से सुरक्षित parallel access संभव होता है
    • interpreter initialization नहीं: uv एक single static binary है, इसलिए pip की तरह Python process शुरू करने की लागत नहीं लगती
    • version information को u64 integer में compact represent किया जाता है, जिससे comparison और hashing तेज़ होते हैं
  • ये चीज़ें performance बढ़ाती हैं, लेकिन पूरे speedup का मुख्य कारण नहीं हैं

मुख्य सीख

  • uv की speed Rust की वजह से नहीं, बल्कि उन चीज़ों की वजह से है जो यह नहीं करता
  • PEP 518·517·621·658 की standardization ने तेज़ package management की नींव रखी, और uv ने legacy removal और modern assumptions के साथ इसे वास्तविकता में बदला
  • pip भी parallel downloads, global cache और metadata-based resolution लागू कर सकता है, लेकिन 15 साल की backward compatibility उसके रास्ते की बड़ी बाधा है
  • नतीजतन pip का धीमा रहना लगभग तय है, और सिर्फ़ वे tools जो नई assumptions से शुरू होते हैं, मूलभूत speed improvement ला सकते हैं
  • दूसरे package managers के लिए सीख यह है कि static metadata, code चलाए बिना dependency discovery, और pre-resolvable structure अनिवार्य हैं
  • Cargo और npm पहले से यही तरीका अपनाते हैं, और वे ecosystems जहाँ dependency जाँचने के लिए code चलाना पड़ता है, वे मूल रूप से धीमे होते हैं

1 टिप्पणियां

 
GN⁺ 2025-12-27
Hacker News टिप्पणियाँ
  • मुझे लगता है कि इस लेख ने uv के performance को कई पहलुओं से अच्छी तरह समझाया है
    इसका Rust में लिखा होना मददगार है, लेकिन पिछले 10 वर्षों में Python ecosystem को setup.py निर्भरता से बाहर लाने के लिए किए गए standardization efforts ने कहीं बड़ी भूमिका निभाई है

    • पहले जब मैं Haskell प्रोजेक्ट्स पर काम करता था, तो भाषा से भी ज़्यादा फायदा इस बात का था कि expert community को चुना जा सकता था
      Rust को भी इसी तरह community की क्षमता ऊपर खींचने वाली वजह से चुना जा सकता है
    • कई Rust rewrite प्रोजेक्ट्स को ऐसा halo effect मिलता है
      वे पुरानी trial-and-error प्रक्रिया को दोबारा देखते हुए बेहतर design कर सकते हैं, और Rust के अपने फायदे जुड़कर एक तरह का ‘one-two punch’ बनाते हैं
  • “uv इसलिए तेज़ नहीं है कि वह Rust में है, बल्कि इसलिए तेज़ है क्योंकि वह कम काम करता है” — इस बात से सहमत हूँ
    लेकिन benchmark के बिना speed factors को तय कर देना जल्दबाज़ी होगी
    PEP 518, 517, 621, 658 का असर बड़ा है, लेकिन compatibility हटाने से कितना फर्क पड़ा, इस पर संदेह है
    और language choice ने optimization पर क्या असर डाला, इस पर भी बात नहीं हुई
    Cargo का TOML parser Python से बहुत तेज़ है, यह भी दिलचस्प है

    • pip के पुराने version और मौजूदा version की तुलना करना भी एक तरह का benchmark हो सकता है
      वास्तव में TOML केवल build के समय पढ़ा जाता है, इसलिए उसका हिस्सा बड़ा नहीं है, लेकिन wheel adoption ने speedup में योगदान दिया है
      संबंधित लेख: setup.py deprecated, wheels are faster
  • rkyv का उपयोग करके की जाने वाली zero-copy deserialization सिर्फ Rust की तकनीक नहीं है
    C/C++ जैसी low-level भाषाओं में भी यह संभव है

    • यहाँ “केवल Rust” कहने का मतलब शायद “Python में संभव नहीं” के अर्थ में है
      “interpreter startup नहीं है” वाली बात भी उसी संदर्भ में है
    • Python में zero-copy लागू करना कठिन है, इसलिए Rust इसे safe और आसान बनाता है, यह मानने लायक है
    • आखिरकार यह चर्चा Rust बनाम Python की तुलना ही है
  • लेख की सामग्री अच्छी है, लेकिन LLM से तराशी गई writing style बहुत कृत्रिम लगती है
    हो सकता है कभी ऐसा समय आए जब LLM की वजह से बिगड़े लेखों को फिर से इंसानी ढंग से बहाल करना पड़े

    • लेखक SBOM और Lockfile पर लेखों के कारण भी HN पर आ चुका है
      वह supply chain security expert लगता है, लेकिन उस लेख में भी LLM वाली धुंधली शैली का असर महसूस हुआ था
    • उल्टा, कुछ लोगों को इसमें बिल्कुल भी LLM जैसी गंध नहीं लगी और यह स्वाभाविक लगा
    • अब अगर किसी लेख से AI वाली गंध आती है, तो मैं उसे तुरंत बंद कर देता हूँ
      एक जैसे fixed prompts हर लेख को एक जैसा बना देते हैं, और यह अफसोसजनक है कि पूरा इंटरनेट एक ही आवाज़ में बोलता हुआ लगने लगता है
  • uv की speed को लेकर इतना उत्साह समझ में नहीं आता
    ज़्यादातर Python users शायद package install speed को अपनी top 10 चिंताओं में भी नहीं रखेंगे
    मैं भी हर दिन Python इस्तेमाल करता हूँ, लेकिन इसका असर उतना महसूस नहीं होता

    • एक पिछली कंपनी में poetry के साथ dependency update में 5–30 मिनट लगते थे
      अगर fail हो जाए, तो फिर से 30 मिनट इंतज़ार करना पड़ता था, और uv सच में काफ़ी सुखद अनुभव था
    • मैं 20 साल से ज़्यादा समय से Python इस्तेमाल कर रहा हूँ, और pip install deployment time का बड़ा हिस्सा लेता रहा है
      caching से speed बढ़ाने की कोशिश में बहुत समय गया है
    • मेरे काम के monolithic app में poetry install में 2 मिनट लगते हैं, जबकि uv sync कुछ सेकंड में खत्म हो जाता है
      हर CI में 2 मिनट बचने का cumulative effect बड़ा होता है
    • uvx sometool चलाते समय भी virtual environment बनाना और dependencies install करना कुछ ही सेकंड में हो जाता है, जिससे workflow पूरी तरह बदल जाता है
    • लंबे समय से Python उपयोगकर्ता होने के नाते, uv की speed मेरे लिए “quality-of-life बदल देने” जैसी है
      अब uv के बिना किसी प्रोजेक्ट पर लौटना कठिन लगता है
  • uv की कुछ speed optimization techniques pip में भी लाई जा सकती हैं
    जैसे: parallel download, .pyc को बाद में बनाना, egg को ignore करना, version check आदि
    लेकिन uv venv को इतना अच्छी तरह संभालता है कि शायद pip को छेड़ने की ज़रूरत ही न पड़े
    आखिर बात यह है कि “यह सिर्फ Rust की वजह से नहीं है”, इसलिए pip के और तेज़ होने की भी गुंजाइश है

  • तेज़ भाषा चुनने वाले programmers के पास अक्सर पहले से performance optimization mindset होता है
    performance पर असर केवल language से नहीं, बल्कि ऐसे रवैये से भी पड़ता है

  • यह दिलचस्प है कि uv python<4.0 upper bound को ignore करता है
    ज़्यादातर packages इसे इस डर से defensively सेट करते हैं कि Python 4 पर कुछ टूट न जाए, जबकि असल में शायद कोई समस्या नहीं होती
    upper-bound restriction वास्तविक समस्याओं से ज़्यादा काल्पनिक समस्याओं को हल करने की कोशिश थी

    • uv सभी upper bounds को ignore नहीं करता, बल्कि लगता है कि केवल 4.0 के मामले में ऐसा करता है
      python<3.0 जैसी constraints अब भी महत्वपूर्ण हैं, इसलिए ऐसे मामलों को रोकना चाहिए
  • PEP 658 का 2023 में लागू होना और uv का 2024 में आना महज़ संयोग नहीं है
    ecosystem तैयार हो चुका था, इसलिए uv जैसे tools संभव हो पाए
    लेकिन जिज्ञासा यह है कि package maintainers ने इस बदलाव को क्यों अपनाया
    जिन लोगों के लिए setup.py ठीक से काम कर रहा था, वे pyproject.toml पर क्यों गए

    • सच तो यह है कि setup.py बहुत लोगों के लिए असुविधाजनक था
      उदाहरण के लिए Requests भी अभी तक पूरी तरह PEP 517/518/621 compatible नहीं है
      डेढ़ साल बीतने पर भी minor release टलती रही, और इस बीच build issues भी आए
    • static declaration ज़्यादा safe और performance-friendly था
      फिर भी सवाल है कि pip इसका पर्याप्त लाभ क्यों नहीं उठा रहा
  • “जिस code path को किया ही नहीं जाता, उसका इंतज़ार नहीं करना पड़ता” — यह अभिव्यक्ति पूरी तरह सटीक नहीं है
    समय तो वही बचाता है जो code path वास्तव में execute नहीं होता
    उदाहरण के लिए .egg support न होना, अगर वह पहले से ही obsolete format है, तो speed पर असर नहीं डालेगा
    अगर यह दिखाने वाला quantitative data होता कि किस चीज़ से कितना समय बचा, तो और अच्छा होता
    फिर भी कुल मिलाकर यह अच्छी तरह व्यवस्थित लेख है