Rust बाइनरीज़ को डिफ़ॉल्ट रूप से छोटा बनाना

Rust के “hello world” binaries लंबे समय से कई मेगाबाइट आकार के होने के लिए आलोचना झेलते रहे हैं, जिसे कई लोग इसकी “zero-cost abstractions” प्रतिष्ठा को कमजोर करने वाला और छोटे C executables के आदी डेवलपर्स को दूर करने वाला मानते हैं। Cargo में एक हालिया बदलाव, जब debuginfo अनुरोध नहीं किया गया हो, तो डिफ़ॉल्ट रूप से standard-library debug symbols को strip कर देगा, जिससे सामान्य release binaries का आकार लगभग 90% घटकर कुछ सौ kilobytes रह जाएगा, जबकि development builds के लिए full symbols उपलब्ध रहेंगे। टिप्पणीकार आधुनिक प्रणालियों बनाम embedded और constrained environments में binary size की महत्ता पर बहस करते हैं, और इस बदलाव को backtraces, panic behavior, link-time optimization, तथा Rust के static-linking, no-stable-ABI design से जुड़े trade-offs के विरुद्ध तौलते हैं.

पहली छापें और बाइनरी आकार एक संकेत के रूप में

  • कई टिप्पणीकार कहते हैं कि कई-एमबी का “hello world” evaluators को तुरंत दूर कर सकता है, खासकर वे C/C++ डेवलपर जो छोटे बाइनरीज़ के आदी हैं।
  • अन्य लोग तर्क देते हैं कि शुरुआती आकार मुख्यतः एक स्थिर लागत है और जैसे-जैसे प्रोग्राम बड़े होते हैं, यह उनके सीमांत विकास का पूर्वानुमान नहीं होता।
  • इस पर बहस है कि क्या “hello world size” abstraction cost के लिए अच्छा proxy है: कुछ सामान्य रूप से हाँ मानते हैं, जबकि अन्य बताते हैं कि Rust का 4MB→400KB बदलाव (debug stripping के जरिए) दिखाता है कि आकार language overhead से नहीं, बल्कि tooling choices से भी बहुत प्रभावित हो सकता है।

~415KB Rust “hello world” में क्या है?

  • जिन प्रमुख योगदानों का उल्लेख किया गया:
    • Backtrace support: stack walking, DWARF parsing, name demangling, path handling, compressed ELF sections.
    • I/O machinery: buffered stdout, synchronization, allocator, vector implementation.
    • Formatting, विशेषकर floats, जो पर्याप्त data tables और corner-case handling पर निर्भर करती है।
  • std का static linking (portability और stable Rust ABI के अभाव के लिए) स्वाभाविक रूप से dynamically linked C program से अधिक चीजें खींच लाता है।

Debug info strip करना और stack traces

  • पिछले व्यवहार में: release binaries में भी std का debug info embedded रहता था, जिससे “hello world” का आकार ~4MB तक बढ़ जाता था।
  • नया default: जब debuginfo अनुरोध नहीं किया गया हो, तब strip = "debuginfo", जो std के DWARF को हटाता है लेकिन runtime behavior को बनाए रखता है।
  • परिणाम: release backtraces line numbers खो देती हैं, लेकिन टिप्पणीकार नोट करते हैं कि user code के लिए debug info के बिना वे वैसे भी बहुत कम उपयोगी थीं।
  • कुछ लोगों को symbols खोने की चिंता है; अन्य external/split debug info और debuginfod को सही दीर्घकालिक पैटर्न मानते हैं।

मैनुअल size tuning और tradeoffs

  • सामान्य recipe: opt-level="z", lto=true, codegen-units=1, panic="abort", साथ में std को panic_abort / panic_immediate_abort के साथ build करना और stripping। इससे आकार दर्जनों KB तक आ सकता है।
  • चर्चा किए गए tradeoffs:
    • size-optimized builds के लिए compilation धीमा, और कभी-कभी runtime भी धीमा।
    • panic="abort" unwinding, panic पर destructors, और कुछ recovery patterns को हटा देता है; इसकी तुलना -fno-exceptions से की गई है।
    • सब कुछ strip करना (केवल debuginfo नहीं) binaries को तोड़ सकता है; --strip-unneeded को विशेष रूप से हाइलाइट किया गया है।

बाइनरी आकार कब मायने रखता है (और कब नहीं)

  • कुछ लोग कहते हैं कि अधिकांश desktop/server उपयोग के लिए 1MB से कम कुछ भी ठीक है; performance और compile time अधिक महत्वपूर्ण हैं।
  • अन्य, खासकर embedded/Linux-on-constrained-devices और कम-resource वाले containers में, इस बात पर जोर देते हैं कि kilobytes भी जुड़कर मायने रखते हैं और यह एक कठोर constraint हो सकता है।
  • एक environmental/efficiency angle भी है: बड़े binaries और बेकार काम को systemic bloat माना जाता है।

Static बनाम dynamic linking और ABI stability

  • Rust डिफ़ॉल्ट रूप से static std उपयोग करता है क्योंकि उसका ABI unstable है; dynamic Rust libraries संभव हैं लेकिन discouraged हैं।
  • स्थिर shared objects के लिए C ABI का उपयोग किया जा सकता है, जिन्हें अन्य भाषाएँ call कर सकती हैं।
  • Embedded Rust अक्सर #![no_std] का उपयोग करता है, जो इस overhead का बड़ा हिस्सा बाइपास कर देता है; लेकिन कई “embedded” Linux systems अभी भी full-fat std binary sizes की चिंता करते हैं।

Project process और attitudes

  • कुछ लोग आलोचना करते हैं कि यह “obvious” issue लगभग 7 साल तक टला रहा, और इसे features पर fundamentals को प्राथमिकता देने का संकेत मानते हैं।
  • अन्य इसे सामान्य prioritization के रूप में देखते हैं: बहुत कम उपयोगकर्ता blocked थे, workarounds मौजूद थे, और बहुत अधिक urgent समस्याएँ ध्यान के लिए प्रतिस्पर्धा कर रही थीं।
  • व्यापक सहमति है कि defaults को बेहतर बनाना, यहाँ तक कि उन मुद्दों के लिए भी जिनके ज्ञात workarounds मौजूद हैं, Rust की polish और perception के लिए महत्वपूर्ण है।