- 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 टिप्पणियां
Hacker News टिप्पणियाँ
मुझे लगता है कि इस लेख ने uv के performance को कई पहलुओं से अच्छी तरह समझाया है
इसका Rust में लिखा होना मददगार है, लेकिन पिछले 10 वर्षों में Python ecosystem को
setup.pyनिर्भरता से बाहर लाने के लिए किए गए standardization efforts ने कहीं बड़ी भूमिका निभाई हैRust को भी इसी तरह community की क्षमता ऊपर खींचने वाली वजह से चुना जा सकता है
वे पुरानी 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 से बहुत तेज़ है, यह भी दिलचस्प है
वास्तव में TOML केवल build के समय पढ़ा जाता है, इसलिए उसका हिस्सा बड़ा नहीं है, लेकिन wheel adoption ने speedup में योगदान दिया है
संबंधित लेख: setup.py deprecated, wheels are faster
rkyvका उपयोग करके की जाने वाली zero-copy deserialization सिर्फ Rust की तकनीक नहीं हैC/C++ जैसी low-level भाषाओं में भी यह संभव है
“interpreter startup नहीं है” वाली बात भी उसी संदर्भ में है
लेख की सामग्री अच्छी है, लेकिन LLM से तराशी गई writing style बहुत कृत्रिम लगती है
हो सकता है कभी ऐसा समय आए जब LLM की वजह से बिगड़े लेखों को फिर से इंसानी ढंग से बहाल करना पड़े
वह supply chain security expert लगता है, लेकिन उस लेख में भी LLM वाली धुंधली शैली का असर महसूस हुआ था
एक जैसे fixed prompts हर लेख को एक जैसा बना देते हैं, और यह अफसोसजनक है कि पूरा इंटरनेट एक ही आवाज़ में बोलता हुआ लगने लगता है
uv की speed को लेकर इतना उत्साह समझ में नहीं आता
ज़्यादातर Python users शायद package install speed को अपनी top 10 चिंताओं में भी नहीं रखेंगे
मैं भी हर दिन Python इस्तेमाल करता हूँ, लेकिन इसका असर उतना महसूस नहीं होता
poetryके साथ dependency update में 5–30 मिनट लगते थेअगर fail हो जाए, तो फिर से 30 मिनट इंतज़ार करना पड़ता था, और uv सच में काफ़ी सुखद अनुभव था
pip installdeployment time का बड़ा हिस्सा लेता रहा हैcaching से speed बढ़ाने की कोशिश में बहुत समय गया है
poetry installमें 2 मिनट लगते हैं, जबकिuv syncकुछ सेकंड में खत्म हो जाता हैहर CI में 2 मिनट बचने का cumulative effect बड़ा होता है
uvx sometoolचलाते समय भी virtual environment बनाना और dependencies install करना कुछ ही सेकंड में हो जाता है, जिससे workflow पूरी तरह बदल जाता हैअब 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.0upper bound को ignore करता हैज़्यादातर packages इसे इस डर से defensively सेट करते हैं कि Python 4 पर कुछ टूट न जाए, जबकि असल में शायद कोई समस्या नहीं होती
upper-bound restriction वास्तविक समस्याओं से ज़्यादा काल्पनिक समस्याओं को हल करने की कोशिश थी
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 भी आए
फिर भी सवाल है कि pip इसका पर्याप्त लाभ क्यों नहीं उठा रहा
“जिस code path को किया ही नहीं जाता, उसका इंतज़ार नहीं करना पड़ता” — यह अभिव्यक्ति पूरी तरह सटीक नहीं है
समय तो वही बचाता है जो code path वास्तव में execute नहीं होता
उदाहरण के लिए
.eggsupport न होना, अगर वह पहले से ही obsolete format है, तो speed पर असर नहीं डालेगाअगर यह दिखाने वाला quantitative data होता कि किस चीज़ से कितना समय बचा, तो और अच्छा होता
फिर भी कुल मिलाकर यह अच्छी तरह व्यवस्थित लेख है