38 पॉइंट द्वारा GN⁺ 2026-01-02 | 1 टिप्पणियां | WhatsApp पर शेयर करें
  • Python के computation, memory और I/O performance metrics को व्यवस्थित रूप से मापने वाले benchmark नतीजे, जिनमें हर operation का समय और memory usage मात्रात्मक रूप से दिखाया गया है
  • स्पीड के लिहाज़ से property access 14ns, list append 29ns, file open 9μs, FastAPI response 8.6μs जैसे विभिन्न operations की relative latency दी गई है
  • मेमोरी के लिहाज़ से empty string 41 bytes, integer 28 bytes, empty list 56 bytes, empty dictionary 64 bytes, empty process 16MB जैसी ठोस संख्याएँ दी गई हैं
  • data structures, serialization, async processing आदि अलग-अलग क्षेत्रों में standard library और alternative libraries (orjson, msgspec आदि) के performance अंतर की तुलना की गई है
  • मुख्य सीख के रूप में Python objects का ऊँचा memory overhead, dict/set lookup की तेज़ी, __slots__ के memory-saving प्रभाव, और async processing के overhead को समझने की ज़रूरत पर ज़ोर दिया गया है

अवलोकन

  • Python developers के लिए जानने लायक performance indicators को संकलित करने वाली सामग्री, जिसमें operation speed और memory usage को वास्तविक मापों के साथ दिखाया गया है
  • benchmark CPython 3.14.2, Mac Mini M4 Pro (ARM, 14-core, 24GB RAM) वातावरण में चलाया गया
  • नतीजे relative comparison पर केंद्रित हैं, और code व data GitHub repository में सार्वजनिक हैं

मेमोरी उपयोग (Memory Costs)

  • खाली Python process 15.73MB memory उपयोग करता है
  • strings का base size 41 bytes है, और हर अतिरिक्त character पर 1 byte बढ़ता है
    • उदाहरण: empty string 41B, 100-character string 141B
  • numeric types में small integers (0–256) 28B, large integer (1000) भी 28B, बहुत बड़ा integer (10ⁱ⁰⁰) 72B, floating point 24B
  • collections का base size: list 56B, dictionary 64B, set 216B
    • 1,000 items होने पर list 35.2KB, dictionary 63.4KB, set 59.6KB
  • class instances: सामान्य class (5 attributes) 694B, __slots__ class 212B
    • 1,000 instances पर सामान्य class 165.2KB, __slots__ class 79.1KB

बुनियादी operations (Basic Operations)

  • arithmetic operations: integer addition 19ns, float addition 18.4ns, integer multiplication 19.4ns
  • string operations: concatenation 39.1ns, f-string 64.9ns, .format() 103ns, % formatting 89.8ns
  • list operations: append() 28.7ns, list comprehension (1,000 items) 9.45μs, वही काम for loop से 11.9μs
    • list comprehension, for loop से लगभग 26% तेज़ है

collection access और iteration

  • key/index access: dictionary lookup 21.9ns, set membership 19ns, list index access 17.6ns
    • list membership (1,000 items) 3.85μs है, जो set/dictionary से लगभग 200 गुना धीमा है
  • length check: len() list पर 18.8ns, dictionary पर 17.6ns, set पर 18ns
  • iteration: list (1,000 items) 7.87μs, dictionary 8.74μs, sum() 1.87μs

class और attributes

  • attribute access speed: सामान्य class और __slots__ class दोनों में read 14.1ns, write लगभग 16ns
  • अन्य operations: @property read 19ns, getattr() 13.8ns, hasattr() 23.8ns
  • __slots__ इस्तेमाल करने पर memory saving 2 गुना से अधिक है, जबकि access speed लगभग समान रहती है

JSON और serialization

  • standard library की तुलना में alternative libraries का performance
    • complex objects को serialize करते समय orjson 310ns पर, json के 2.65μs से 8 गुना से अधिक तेज़ है
    • msgspec 445ns, ujson 1.64μs
  • deserialization में भी orjson 839ns के साथ सबसे तेज़ है
  • Pydantic: model_dump_json() 1.54μs, model_validate_json() 2.99μs

web frameworks

  • समान JSON response के आधार पर FastAPI 8.63μs, Starlette 8.01μs, Litestar 8.19μs, Flask 16.5μs, Django 18.1μs
  • FastAPI की response speed, Django से लगभग 2 गुना तेज़ है

file I/O

  • file open/close 9.05μs, 1KB read 10μs, 1MB read 33.6μs
  • write: 1KB 35.1μs, 1MB 207μs
  • Pickle, json की तुलना में serialization और deserialization दोनों में लगभग 2 गुना तेज़ है (pickle.dumps() 1.3μs, json.dumps() 2.72μs)

database और cache

  • SQLite: insert 192μs, select 3.57μs, update 5.22μs
  • diskcache: set 23.9μs, get 4.25μs
  • MongoDB: insert 119μs, find_one 121μs
  • read speed में SQLite सबसे तेज़ है, जबकि diskcache की write performance बेहतर है

function calls और exceptions

  • function call: empty function 22.4ns, method 23.3ns, lambda 19.7ns
  • exception handling: try/except (normal path) 21.5ns, exception होने पर 139ns
  • type checking: isinstance() 18.3ns, type() comparison 21.8ns

async overhead

  • coroutine creation 47ns, run_until_complete 27.6μs
  • asyncio.sleep(0) 39.4μs, gather(10 coroutines) 55μs
  • synchronous function call (20ns) की तुलना में async execution (28μs) लगभग 1,000 गुना धीमा है

मुख्य सीख (Key Takeaways)

  • Python objects का memory overhead बड़ा होता है; खाली list भी 56 bytes लेती है
  • dictionary और set lookup list search से सैकड़ों गुना तेज़ हैं
  • orjson, msgspec जैसी alternative JSON libraries standard से 3–8 गुना तेज़ हैं
  • async processing का overhead बड़ा है, इसलिए इसका उपयोग केवल तब करना चाहिए जब parallelism की वास्तव में ज़रूरत हो
  • __slots__ मेमोरी को आधे से भी कम कर सकता है, और performance loss लगभग नहीं होता

1 टिप्पणियां

 
GN⁺ 2026-01-02
Hacker News टिप्पणियाँ
  • बहुत से लोग कहते हैं कि “अगर Python में latency नंबरों की चिंता करनी पड़ रही है, तो कोई दूसरी भाषा इस्तेमाल करनी चाहिए”, लेकिन मैं इससे सहमत नहीं हूँ
    Instagram, Dropbox, OpenAI जैसे बड़े codebase भी Python पर बढ़े हैं। आखिरकार performance समस्याएँ आती ही हैं, और दूसरी भाषा में जाए बिना Python के भीतर उन्हें हल कर पाने की क्षमता महत्वपूर्ण है
    ज़्यादातर performance समस्याएँ भाषा की सीमा नहीं बल्कि inefficient code की वजह से होती हैं। उदाहरण के लिए, ऐसा loop जो बिना ज़रूरत function call को 10,000 बार दोहराता हो
    मैंने बनाया हुआ Python latency quiz भी देखने लायक है

    • मैं Python में लिखे systems की performance optimization पर काम करता हूँ। लेकिन ये नंबर तब तक वास्तव में मायने नहीं रखते जब तक ये समस्या न बन जाएँ। समस्या आने पर मैं सीधे मापता हूँ। method call बचाने के हिसाब से code लिखने लगेंगे तो Python के फ़ायदे खो बैठेंगे
    • Python बुनियादी operations में भी धीमा है। function call या dictionary access जैसे सरल कामों में भी। सच तो यह है कि Python बचा हुआ है C/C++ आधारित libraries (जैसे Numpy) की वजह से
    • ऐसे नंबर सिर्फ Python की समस्या नहीं हैं। Zig में भी CPU cycle और cache miss पर ध्यान दिया जाता है। हर भाषा में कुछ operations की latency होती है। Python न इस्तेमाल करने की वजहें हो सकती हैं, लेकिन यह उनमें से एक नहीं है
    • कुछ operations को alternative modules से बेहतर किया जा सकता है। ऐसी जानकारी होना महत्वपूर्ण है, लेकिन जिसे सच में इसकी ज़रूरत होगी, वह शायद पहले से जानता होगा। फिर भी Python prototyping के लिए शानदार भाषा है
    • हमारा build system भी Python में है, इसलिए performance सुधारते हुए भी Python बनाए रखना चाहता हूँ। इसी वजह से ये नंबर बहुत महत्वपूर्ण हैं
  • विडंबना यह है कि जिस क्षण ऐसे नंबर महत्वपूर्ण हो जाते हैं, Python उस काम के लिए सही tool नहीं रह जाता

    • Python code को बनाए रखते हुए मुख्य performance हिस्सों को C या Rust extension में उतार देना व्यावहारिक तरीका है। numpy, pandas, PyTorch ऐसा ही करते हैं।
      व्यवहार में code को instrument करना (pyspy जैसे tools से) और bottleneck ढूँढना ज़्यादा महत्वपूर्ण है। अगर आप list में element जोड़ने की speed की चिंता कर रहे हैं, तो शायद वह operation Python में होना ही नहीं चाहिए
    • मैंने 20 साल Python के साथ काम किया है, लेकिन मुझे कभी ऐसे नंबर जानने की ज़रूरत नहीं पड़ी। इसकी जगह profiling और Cython, SWIG, JIT जैसे tools से काम निकाला
    • अगर कोई application इस स्तर पर है कि ऐसे नंबर महत्वपूर्ण हो जाएँ, तो Python बहुत high-level language है और उसमें optimization कठिन हो जाती है
    • लेकिन मैंने Python में बड़े data pipeline बनाए हैं। turbodbc + pandas का संयोजन C++ स्तर की speed देता है। memory ज़्यादा लगती है, लेकिन manpower cost को देखें तो यह कहीं ज़्यादा efficient है।
      Python और C की interoperability की वजह से यह approach संभव है। Zig भी लगातार बेहतर हो रहा है। Python से मैं विमान नहीं उड़ाऊँगा, लेकिन resource-sense फिर भी महत्वपूर्ण है
    • ऐसे नंबर आख़िरी उपाय हैं। disk I/O, network, algorithmic complexity जैसे सामान्य bottleneck हल करने के बाद ही इन्हें देखना चाहिए
  • खाली string कितने bytes लेती है, यह जानना बहुत मायने नहीं रखता। महत्वपूर्ण बात है time·space complexity को समझना।
    यह जानने से ज़्यादा कि int 28 bytes का है, यह समझना ज़रूरी है कि program performance requirements पूरी कर रहा है या नहीं, और अगर नहीं, तो बेहतर algorithm ढूँढना चाहिए

    • लेकिन performance हमेशा leaky abstraction होती है। हम ध्यान दें या न दें, यह पूरे code पर असर डालती है।
      उदाहरण के लिए, string concatenation का O(n²) होना Python के f-string design को भी प्रभावित करता है।
      dictionary तेज़ होने की वजह से Python भर में व्यापक रूप से इस्तेमाल होती है।
      ऐसे नंबर उस implicit knowledge को numbers के ज़रिए justify करने का काम करते हैं
    • int का 28 bytes होना, उन समस्याओं में सचमुच महत्वपूर्ण है जहाँ बहुत बड़ी संख्या में objects बनाने पड़ते हैं।
      Eric Raymond ने Reposurgeon के साथ GCC migrate करते समय जो समस्या झेली थी, उस पर यह लेख याद आता है
  • शीर्षक थोड़ा भ्रमित करने वाला है; दरअसल यह Jeff Dean के 2012 के पेपर “Latency Numbers Every Programmer Should Know” की पैरोडी है।
    इस तरह के title joke CS papers में आम हैं

    • अगर कोई “latency numbers considered harmful is all you need” जैसा शीर्षक लेकर पेपर लिख दे, तो शायद अकादमिक दुनिया में बहुत लोकप्रिय हो जाए
    • लेकिन लगता है इस लेख के लेखक ने इसे गंभीरता से लिखा है। पाठकों ने शीर्षक को गलत नहीं समझा
    • शीर्षक सही बैठने के लिए ज़रूरी है कि ये नंबर वास्तव में useful हों, लेकिन ये बहुत ज़्यादा हैं और व्यावहारिक नहीं लगते
    • संदर्भ के लिए, Jeff Dean का मूल लेख 2012 से काफ़ी पहले लिखा गया लगता है।
      यह Google के शुरुआती search engine में RAM vs Disk design के लिए आंतरिक सामग्री थी।
      बाद में flash memory आने से नंबर बदल गए, और यह किस्सा भी है कि Jeff ने genomic data को flash से सीधे serve करने के लिए compression algorithm बनाया था
  • ज़्यादातर Python developers को ऐसे low-level performance details से अधिक महत्वपूर्ण चीज़ों पर ध्यान देना चाहिए।
    ऐसी सामग्री reference के रूप में अच्छी है, लेकिन व्यवहार में इसकी ज़रूरत कम ही पड़ती है

    • लेकिन जिन tools का आप इस्तेमाल करते हैं, उनके बारे में सामान्य ज्ञान हमेशा मूल्यवान होता है। यह बौद्धिक संपत्ति जैसा है और कुछ स्थितियों में बहुत काम आता है
    • जब सीमा आ जाए, तो C में implemented module ढूँढ लें या खुद लिख लें। Python मूल रूप से इसी तरह आगे बढ़ा है
    • मैंने भी ज़्यादातर मामलों में “काफ़ी तेज़ है” वाली समझ के साथ काम किया है। इस सामग्री ने उस समझ को numbers में verify कर दिया
  • string size की व्याख्या गलत है। Python में प्रति character 1, 2, 4 bytes इस्तेमाल करने वाले तीन प्रकार के string types होते हैं
    अधिक जानकारी के लिए यह blog देखें

  • लेख का शीर्षक और उदाहरण कुछ हद तक सटीक नहीं हैं।
    उदाहरण के लिए, “item in set, item in list से 200 गुना तेज़ है” दरअसल membership test की बात है, iteration speed की तुलना नहीं।
    फिर भी कुल मिलाकर format और structure आकर्षक हैं

  • class instance creation time की माप शामिल नहीं है।
    मैंने code refactoring के बाद साधारण list structure को class में बदला, और execution time कुछ microseconds → कुछ seconds हो गया।
    काश इस तरह के मामलों की भी measurement होती

    • इससे वह मज़ाक याद आता है जिसमें डॉक्टर से कहा जाता है, “यह करने पर दर्द होता है”, और डॉक्टर जवाब देता है, “तो मत कीजिए।”
      शायद class का overuse समस्या हो सकता है। कुछ मामलों में साधारण list structure बेहतर होता है
    • class instance creation अपने आप में आम तौर पर performance समस्या नहीं होती।
      ज़्यादा संभावना है कि object-oriented approach का गलत इस्तेमाल हुआ हो।
      code को StackOverflow या CodeReview.SE पर डालकर feedback लेना बेहतर होगा
  • मैंने इस लेख को इस नज़रिए से दिलचस्प पाया कि “क्या modern Python में कुछ बुनियादी रूप से गड़बड़ है।”
    लेकिन मैं इस दावे से सहमत नहीं हूँ कि ऐसे नंबर “सबको जानने चाहिए।”
    कुछ मुख्य operations का सहज अंदाज़ा होना काफ़ी है

  • Python का small int caching रेंज 0~256 नहीं बल्कि -5~256 है।
    इसी वजह से शुरुआती लोग अक्सर identity (is) और equality (==) को लेकर भ्रमित हो जाते हैं

    • Java में भी ऐसा ही व्यवहार मिलता है। शुरुआती लोगों के लिए यह उलझन पैदा कर सकता है