C++ में extern "C" का जादू: कोड की गति और अनुकूलता

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

extern "C" के पीछे क्या छिपा है: मिथक और वास्तविकता

\n\n

यदि आपने कभी C++ कोड लिखा है जिसे C लाइब्रेरी के साथ काम करना था, तो आपने निश्चित रूप से जादुई संरचना extern "C" देखी होगी। पहली नज़र में - यह सिर्फ एक सेवा निर्देश है। लेकिन इसके पीछे निम्न-स्तरीय अनुकूलन और समझौतों की एक पूरी दुनिया छिपी है। इस लेख में, हम विश्लेषण करेंगे कि extern "C" प्रदर्शन को कैसे प्रभावित करता है, और यह ज्ञान आपके कोड को दसियों प्रतिशत तक तेज़ क्यों बना सकता है।

\n\n

हम जिस प्रश्न पर विचार करेंगे, वह Stack Overflow पर सबसे लोकप्रिय में से एक है (100,000 से अधिक बार देखा गया)। और यह आश्चर्य की बात नहीं है: extern "C" को समझना कुशल कोड लिखने की कुंजी है जो C और C++ दोनों वातावरणों में समान रूप से अच्छी तरह से काम करता है। आइए कंपाइलर के हुड के नीचे झाँकें।

\n\n

वास्तव में extern "C" क्या है?

\n\n

तकनीकी रूप से extern "C" लिंकर को एक निर्देश है, जो कॉलिंग कन्वेंशन और नेम मैंगलिंग को बदलता है। लेकिन अगर सरल शब्दों में कहें - यह C की दुनिया और C++ की दुनिया के बीच एक पुल है।

\n\n

जब आप लिखते हैं:

\n\n
extern "C" void myFunction(int x);
\n\n

आप कंपाइलर से कह रहे हैं: "अरे, इस फ़ंक्शन के साथ वैसा ही व्यवहार करो जैसे कि यह शुद्ध C में लिखा गया हो।" इसका मतलब है:

\n\n
    \n
  • नेम मैंगलिंग बंद करना - फ़ंक्शन का नाम वैसा ही रहता है जैसा आपने लिखा है (_Z10myFunctioni जैसे C++ सजावट के बिना)।
  • \n
  • C-शैली लिंकिंग का उपयोग करना - फ़ंक्शन को बिना किसी अतिरिक्त रूपांतरण के C कोड से कॉल किया जा सकता है।
  • \n
  • कुछ सीमाएँ - फ़ंक्शन ओवरलोडिंग, टेम्पलेट या अपवादों का उपयोग नहीं किया जा सकता।
  • \n
\n\n

प्रदर्शन पर प्रभाव: आंकड़े और तथ्य

\n\n

बहुत से लोग सोचते हैं कि extern "C" अनुकूलता के लिए सिर्फ एक सिंटैक्टिक शुगर है। वास्तव में, यह अनुकूलन का एक शक्तिशाली उपकरण है। आइए वास्तविक बेंचमार्क देखें।

\n\n

1. नेम मैंगलिंग की अनुपस्थिति लिंकिंग को गति देती है

\n\n

C++ में, प्रत्येक फ़ंक्शन नाम "डेकोरेटेड" होता है - कंपाइलर तर्कों के प्रकार, नेमस्पेस आदि के बारे में जानकारी जोड़ता है। यह फ़ंक्शन ओवरलोडिंग को लागू करने की अनुमति देता है। लेकिन इसके लिए भुगतान करना पड़ता है:

\n\n
    \n
  • ऑब्जेक्ट फ़ाइलों में लंबे नाम।
  • \n
  • प्रतीकों को हल करने के लिए लिंकर का अतिरिक्त कार्य।
  • \n
  • बिल्ड समय में वृद्धि (विशेषकर बड़ी परियोजनाओं में)।
  • \n
\n\n

extern "C" के साथ, नाम छोटे रहते हैं। हजारों बाहरी फ़ंक्शन वाली परियोजनाओं में (उदाहरण के लिए, एक बड़ी C-लाइब्रेरी कनेक्ट करते समय), यह लिंकिंग समय को 10-20% तक कम कर सकता है।

\n\n

2. बिना मध्यस्थ के सीधा कॉल

\n\n

जब आप किसी फ़ंक्शन को extern "C" के रूप में घोषित करते हैं, तो कंपाइलर ठीक से जानता है कि यह कोई वर्चुअल फ़ंक्शन, क्लास मेथड या टेम्पलेट नहीं है। यह कर सकता है:

\n\n
    \n
  • अधिक आक्रामक इनलाइनाइज़ेशन लागू करना (यदि फ़ंक्शन उसी ट्रांसलेशन यूनिट में परिभाषित है)।
  • \n
  • डायनामिक टाइप (RTTI) की जाँच के लिए कोड उत्पन्न नहीं करना।
  • \n
  • फ़ंक्शन के सरल प्रोलॉग/एपिलॉग का उपयोग करना।
  • \n
\n\n

तुलना के लिए कोड उदाहरण:

\n\n
// C++ शैली (नेम मैंगलिंग के साथ)\nvoid cpp_function(int a, double b) {\n    // जटिल गणनाएँ\n}\n\n// C शैली (extern "C")\nextern "C" void c_function(int a, double b) {\n    // वही गणनाएँ\n}
\n\n

इसे -O2 फ्लैग के साथ कंपाइल करें और असेंबली कोड देखें। extern "C" के मामले में, कॉल 2-3 निर्देश छोटा होगा - एक छोटी सी बात, लेकिन दस लाख पुनरावृत्तियों के लूप में, यह 5-10% का लाभ देता है।

\n\n

3. टेल कॉल ऑप्टिमाइज़ेशन

\n\n

कंपाइलर के लिए extern "C" फ़ंक्शन के लिए टेल कॉल ऑप्टिमाइज़ेशन को अनुकूलित करना आसान है, क्योंकि C++ संदर्भ (जैसे अपवाद स्टैक) को संरक्षित करने की कोई आवश्यकता नहीं है। रिकर्सिव एल्गोरिदम में, यह गति में दोगुना लाभ दे सकता है।

\n

ब्लॉग

पुस्तक अनुशंसाएँ