Python प्रोग्रामर को जानने चाहिए ये प्रमुख performance metrics
(mkennedy.codes)- 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
- 1,000 instances पर सामान्य class 165.2KB,
बुनियादी 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:
@propertyread 19ns,getattr()13.8ns,hasattr()23.8ns __slots__इस्तेमाल करने पर memory saving 2 गुना से अधिक है, जबकि access speed लगभग समान रहती है
JSON और serialization
- standard library की तुलना में alternative libraries का performance
- complex objects को serialize करते समय
orjson310ns पर,jsonके 2.65μs से 8 गुना से अधिक तेज़ है msgspec445ns,ujson1.64μs
- complex objects को serialize करते समय
- deserialization में भी
orjson839ns के साथ सबसे तेज़ है - 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_complete27.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 टिप्पणियां
Hacker News टिप्पणियाँ
बहुत से लोग कहते हैं कि “अगर Python में latency नंबरों की चिंता करनी पड़ रही है, तो कोई दूसरी भाषा इस्तेमाल करनी चाहिए”, लेकिन मैं इससे सहमत नहीं हूँ
Instagram, Dropbox, OpenAI जैसे बड़े codebase भी Python पर बढ़े हैं। आखिरकार performance समस्याएँ आती ही हैं, और दूसरी भाषा में जाए बिना Python के भीतर उन्हें हल कर पाने की क्षमता महत्वपूर्ण है
ज़्यादातर performance समस्याएँ भाषा की सीमा नहीं बल्कि inefficient code की वजह से होती हैं। उदाहरण के लिए, ऐसा loop जो बिना ज़रूरत function call को 10,000 बार दोहराता हो
मैंने बनाया हुआ Python latency quiz भी देखने लायक है
विडंबना यह है कि जिस क्षण ऐसे नंबर महत्वपूर्ण हो जाते हैं, Python उस काम के लिए सही tool नहीं रह जाता
व्यवहार में code को instrument करना (pyspy जैसे tools से) और bottleneck ढूँढना ज़्यादा महत्वपूर्ण है। अगर आप list में element जोड़ने की speed की चिंता कर रहे हैं, तो शायद वह operation Python में होना ही नहीं चाहिए
Python और C की interoperability की वजह से यह approach संभव है। Zig भी लगातार बेहतर हो रहा है। Python से मैं विमान नहीं उड़ाऊँगा, लेकिन resource-sense फिर भी महत्वपूर्ण है
खाली string कितने bytes लेती है, यह जानना बहुत मायने नहीं रखता। महत्वपूर्ण बात है time·space complexity को समझना।
यह जानने से ज़्यादा कि int 28 bytes का है, यह समझना ज़रूरी है कि program performance requirements पूरी कर रहा है या नहीं, और अगर नहीं, तो बेहतर algorithm ढूँढना चाहिए
उदाहरण के लिए, string concatenation का O(n²) होना Python के f-string design को भी प्रभावित करता है।
dictionary तेज़ होने की वजह से Python भर में व्यापक रूप से इस्तेमाल होती है।
ऐसे नंबर उस implicit knowledge को numbers के ज़रिए justify करने का काम करते हैं
Eric Raymond ने Reposurgeon के साथ GCC migrate करते समय जो समस्या झेली थी, उस पर यह लेख याद आता है
शीर्षक थोड़ा भ्रमित करने वाला है; दरअसल यह Jeff Dean के 2012 के पेपर “Latency Numbers Every Programmer Should Know” की पैरोडी है।
इस तरह के title joke CS papers में आम हैं
यह Google के शुरुआती search engine में RAM vs Disk design के लिए आंतरिक सामग्री थी।
बाद में flash memory आने से नंबर बदल गए, और यह किस्सा भी है कि Jeff ने genomic data को flash से सीधे serve करने के लिए compression algorithm बनाया था
ज़्यादातर Python developers को ऐसे low-level performance details से अधिक महत्वपूर्ण चीज़ों पर ध्यान देना चाहिए।
ऐसी सामग्री reference के रूप में अच्छी है, लेकिन व्यवहार में इसकी ज़रूरत कम ही पड़ती है
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 बेहतर होता है
ज़्यादा संभावना है कि object-oriented approach का गलत इस्तेमाल हुआ हो।
code को StackOverflow या CodeReview.SE पर डालकर feedback लेना बेहतर होगा
मैंने इस लेख को इस नज़रिए से दिलचस्प पाया कि “क्या modern Python में कुछ बुनियादी रूप से गड़बड़ है।”
लेकिन मैं इस दावे से सहमत नहीं हूँ कि ऐसे नंबर “सबको जानने चाहिए।”
कुछ मुख्य operations का सहज अंदाज़ा होना काफ़ी है
Python का small int caching रेंज 0~256 नहीं बल्कि -5~256 है।
इसी वजह से शुरुआती लोग अक्सर identity (is) और equality (==) को लेकर भ्रमित हो जाते हैं