C ++ में इनलाइन कार्यों का लाभ?


254

C ++ में इनलाइन कार्यों का उपयोग करने के क्या फायदे / नुकसान हैं? मैं देखता हूं कि यह केवल उस कोड के लिए प्रदर्शन बढ़ाता है जो संकलक आउटपुट करता है, लेकिन आज के अनुकूलित संकलक, तेज सीपीयू, विशाल मेमोरी आदि (1980 की तरह नहीं <जहां स्मृति दुर्लभ थी और 100KB स्मृति में सब कुछ फिट होना था) क्या फायदे क्या आज उनके पास हैं?


48
यह उन सवालों में से एक है जहां सामान्य ज्ञान गलत है। हर कोई मानक COMP विज्ञान जवाब के साथ जवाब दिया है। (इनलाइनिंग फ़ंक्शन कॉल की लागत बचाता है लेकिन कोड आकार बढ़ाता है)। बकवास। यह कंपाइलर को अधिक ऑप्टिमाइज़ेशन लागू करने के लिए एक सरल तंत्र प्रदान करता है।
मार्टिन यॉर्क

37
यह उन उत्तरों में से एक है जो टिप्पणियों के रूप में प्रस्तुत करते हैं। यदि आपको कोई उत्तर पसंद नहीं आया है, तो अपना उत्तर पोस्ट करें और देखें कि यह कैसे जाता है।
डेव वान डे आईंड

10
इस प्रश्न का आधार त्रुटिपूर्ण है। C ++ इनलाइन कार्यों का संकलन के दौरान संकलक के साथ बहुत कम संबंध है। यह दुर्भाग्यपूर्ण है कि inlinec ++ कीवर्ड है और इनलाइनिंग कंपाइलर ऑप्टिमाइज़ेशन तकनीक है। यह प्रश्न देखें कि " मुझे inlineकिसी फ़ंक्शन / विधि के लिए कीवर्ड कब लिखना चाहिए " सही उत्तर के लिए।
deft_code

3
@JoseVega आपके लिंक में गड़बड़ी हो गई - वर्तमान लिंक exforsys.com/tutorials/c-plus-plus/inline-functions.html

जवाबों:


143

इनलाइन फ़ंक्शंस तेज़ होते हैं क्योंकि आपको स्टैक को पैरामीटर और रिटर्न एड्रेस की तरह पुश / पॉप करने की आवश्यकता नहीं होती है; हालाँकि, यह आपके बाइनरी को थोड़ा बड़ा बनाता है।

क्या यह एक महत्वपूर्ण अंतर है? अधिकांश के लिए आधुनिक हार्डवेयर पर पर्याप्त रूप से नहीं। लेकिन यह एक अंतर बना सकता है, जो कुछ लोगों के लिए पर्याप्त है।

कुछ इनलाइन को चिह्नित करने से आपको यह गारंटी नहीं मिलती है कि यह इनलाइन होगा। यह कंपाइलर का सुझाव मात्र है। कभी-कभी यह संभव नहीं होता है जैसे जब आपके पास कोई वर्चुअल फ़ंक्शन होता है, या जब पुनरावर्ती शामिल होता है। और कभी-कभी कंपाइलर सिर्फ इसका इस्तेमाल नहीं करने का विकल्प चुनता है।

मैं इस स्थिति को देख सकता हूं जैसे कि यह पता लगाने योग्य अंतर बनाता है:

inline int aplusb_pow2(int a, int b) {
  return (a + b)*(a + b) ;
}

for(int a = 0; a < 900000; ++a)
    for(int b = 0; b < 900000; ++b)
        aplusb_pow2(a, b);

26
जैसा कि मुझे संदेह था कि इनलाइनिंग से ऊपर को कोई फर्क नहीं पड़ता। 4.01 gcc के साथ संकलित। संस्करण 1 को इनलाइनिंग का उपयोग करने के लिए मजबूर किया गया: 48.318u 1.042s 5: 51.39 99.4% 0 + 0k 0 + 0io 0pf + 0w संस्करण 2 ने कोई भी inlining 348.311u 1.019s 5: 52.31 99.1% 0 + 0k 0 + 0io 0pf + 0w को मजबूर किया। एक अच्छा उदाहरण था सामान्य ज्ञान गलत है।
मार्टिन यॉर्क

36
जबकि कॉल ही वास्तव में मायने रखता है, यह केवल मामूली लाभ है जिसे आप इनलाइन का उपयोग करके प्राप्त करते हैं। प्रमुख लाभ यह है कि कंपाइलर अब यह देखता है कि पॉइंटर्स एक-दूसरे को उर्फ ​​नहीं करते हैं, जहां कॉलर के चर कैली और इतने पर समाप्त होते हैं। इस प्रकार, निम्नलिखित अनुकूलन अधिक मायने रखता है।
जोहान्स शाउब -

31
इस स्निपेट में शायद कोई फर्क नहीं पड़ता क्योंकि फ़ंक्शन के परिणाम का उपयोग कभी नहीं किया जाता है और न ही फ़ंक्शन के दुष्प्रभाव होते हैं। हमें छवि प्रसंस्करण में एक औसत दर्जे का प्रदर्शन लाभ दिखाई देता है।
मरिंथ

4
कोई अंतर नहीं होने का कारण यह हो सकता है कि कंपाइलर अपने हिसाब से इनलाइन कर सकता है; या यह कि कोड छोटा है इसलिए कोई कोड प्रीफ़ैच इश्यू नहीं हैं।
einpoklum

3
@einpoklum कंपाइलर ने उसके कारण पूरे लूप को अनुकूलित भी किया हो सकता है।
no --zɐɹƆ

197

लाभ

  • अपने कोड को इनलाइन करके, जहां इसकी आवश्यकता है, आपका प्रोग्राम फ़ंक्शन कॉल और रिटर्न भागों में कम समय बिताएगा। यह आपके कोड को तेजी से आगे बढ़ाने के लिए माना जाता है, यहां तक ​​कि यह बड़ा हो जाता है (नीचे देखें)। ट्रिवियल एक्सेसर्स को सम्मिलित करना प्रभावी इनलाइनिंग का एक उदाहरण हो सकता है।
  • इसे इनलाइन के रूप में चिह्नित करके, आप एक हेडर फाइल में एक फंक्शन डेफिनिशन डाल सकते हैं (यानी इसे लिंक कंप्लेन किए बिना कई कंप्लायंस यूनिट में शामिल किया जा सकता है)

नुकसान

  • यह आपके कोड को बड़ा बना सकता है (यानी यदि आप गैर-तुच्छ कार्यों के लिए इनलाइन का उपयोग करते हैं)। इस प्रकार, यह संकलक से अनुकूलन को पराजित कर सकता है और अनुकूलन को पराजित कर सकता है।
  • यह आपके एनकैप्सुलेशन को थोड़ा तोड़ देता है क्योंकि यह आपके ऑब्जेक्ट प्रोसेसिंग के आंतरिक को उजागर करता है (लेकिन फिर, प्रत्येक "निजी" सदस्य भी होगा)। इसका मतलब यह है कि आपको PImpl पैटर्न में इनलाइनिंग का उपयोग नहीं करना चाहिए।
  • यह आपके एनकैप्सुलेशन 2 को थोड़ा तोड़ देता है: C ++ इनलाइनिंग को संकलन समय पर हल किया जाता है। जिसका अर्थ है कि आपको इनलाइन फ़ंक्शन के कोड को बदलना चाहिए, आपको यह सुनिश्चित करने के लिए सभी कोड को फिर से इकट्ठा करने की आवश्यकता होगी कि यह सुनिश्चित हो कि इसे अपडेट किया जाएगा (इसी कारण से, मैं फ़ंक्शन मापदंडों के लिए डिफ़ॉल्ट मानों से बचता हूं)
  • जब हेडर में उपयोग किया जाता है, तो यह आपकी हेडर फ़ाइल को बड़ा बनाता है, और इस प्रकार, कोड के साथ दिलचस्प informations (जैसे कक्षा विधियों की सूची) को पतला करेगा, उपयोगकर्ता को इसकी परवाह नहीं है (यही कारण है कि मैं एक के अंदर इनलाइन फ़ंक्शन घोषित करता हूं क्लास, लेकिन इसे क्लास बॉडी के बाद हेडर में परिभाषित करेगा, और क्लास बॉडी के अंदर कभी नहीं)।

इनलाइनिंग मैजिक

  • संकलक आपके द्वारा इनलाइन के रूप में चिह्नित किए गए कार्यों को इनलाइन कर सकता है या नहीं कर सकता है; यह इनलाइन फ़ंक्शन को भी संकलन या लिंकिंग समय पर इनलाइन के रूप में चिह्नित नहीं करने का निर्णय ले सकता है।
  • इनलाइन कम्पाइलर द्वारा नियंत्रित कॉपी / पेस्ट की तरह काम करता है, जो एक प्री-प्रोसेसर मैक्रो से काफी अलग है: मैक्रो को जबरन इनबिल्ट किया जाएगा, सभी नेमस्पेस और कोड को प्रदूषित करेगा, आसानी से डिबग करने योग्य नहीं होगा, और किया भी जाएगा यदि संकलक ने इसे अक्षम के रूप में शासित किया होगा।
  • कक्षा के शरीर के अंदर परिभाषित एक कक्षा की प्रत्येक विधि को "इनलाइन" माना जाता है (भले ही कंपाइलर अभी भी इसे इनलाइन नहीं करने का निर्णय ले सकता है
  • वर्चुअल तरीके अयोग्य नहीं माने जाते। फिर भी, कभी-कभी, जब कंपाइलर सुनिश्चित कर सकता है कि ऑब्जेक्ट का प्रकार (यानी ऑब्जेक्ट को उसी फ़ंक्शन बॉडी के अंदर घोषित किया गया था और निर्मित किया गया था), यहां तक ​​कि एक वर्चुअल फ़ंक्शन भी इनलाइन होगा क्योंकि कंपाइलर ऑब्जेक्ट के प्रकार को ठीक से जानता है।
  • टेम्प्लेट मेथड्स / फ़ंक्शंस हमेशा इनबिल्ड नहीं होते हैं (हेडर में उनकी उपस्थिति उन्हें स्वचालित रूप से इनलाइन नहीं करेगी)।
  • "इनलाइन" के बाद अगला चरण टेम्पलेट मेटाप्रोग्रामिंग है। Ie संकलन समय पर आपके कोड को "इनलाइन" करके, कभी-कभी, कंपाइलर किसी फ़ंक्शन के अंतिम परिणाम को घटा सकता है ... इसलिए एक जटिल एल्गोरिथ्म को कभी-कभी एक प्रकार के return 42 ;बयान में कम किया जा सकता है । यह मेरे लिए चरम inlining है । यह वास्तविक जीवन में शायद ही कभी होता है, यह संकलन समय को लंबे समय तक बनाता है, आपके कोड को ब्लोट नहीं करेगा, और आपके कोड को तेज कर देगा। लेकिन कब्र की तरह, इसे हर जगह लागू करने की कोशिश न करें क्योंकि अधिकांश प्रसंस्करण इस तरह से हल नहीं किए जा सकते हैं ... फिर भी, यह वैसे भी शांत है ...
    : -प

आपने कहा कि यह आपके एनकैप्सुलेशन को थोड़ा तोड़ देता है। क्या आप इसे एक उदाहरण का उपयोग करके समझाएंगे?
नाशक

6
@PravasiMeet: यह C ++ है। मान लें कि आप किसी क्लाइंट को DLL / शेयर्ड लाइब्रेरी डिलीवर करते हैं, जो इसके खिलाफ कंप्लेन करता है। इनलाइन फ़ंक्शन फू, सदस्य चर X का उपयोग करना और काम Y करने से ग्राहक के कोड में इनबिल्ट हो जाएगा। मान लें कि आपको अपने DLL का एक अपडेटेड वर्जन देने की आवश्यकता है जहाँ आपने Z में मेंबर वेरिएबल को बदल दिया है, और काम Y के अलावा एक काम YY जोड़ दिया है। क्लाइंट सिर्फ DLL को अपने प्रोजेक्ट में कॉपी करता है, और BOOM, क्योंकि foo का कोड उनके बाइनरी में आपके द्वारा लिखा गया अपडेटेड कोड नहीं है ... क्लाइंट के पास आपके निजी कोड तक कानूनी पहुंच नहीं होने के बावजूद, इनलाइनिंग इसे काफी "सार्वजनिक" बनाती है।
पियरसबल

@paercebal अपने दूसरे से अंतिम बुलेट पॉइंट के बारे में, क्या आप एक उदाहरण दे सकते हैं कि फ़ंक्शन टेम्पलेट इनलाइन नहीं है ? मुझे लगा कि वे हमेशा इनलाइन थे, हालांकि मेरे पास अब एक संदर्भ काम नहीं है (एक साधारण परीक्षण हालांकि इसकी पुष्टि करता है)।
कोनराड रुडोल्फ

@KonradRudolph n4594 में मैं देखता हूं 3.2/6: There can be more than one definition of [..] inline function with external linkage [..] non-static function template:। 5.1.5 / 6 पर For a generic lambda, the closure type has a public inline function call operator member template। और 7.1.2/2: the use of inline keyword is to declare an inline functionजहां यह कॉल के बिंदु पर फ़ंक्शन बॉडी को इनलाइन करने का सुझाव है। इसलिए, मैं यह निष्कर्ष निकालता हूं कि भले ही वे समान व्यवहार कर सकें, इनलाइन फ़ंक्शंस और फ़ंक्शन टेम्प्लेट अभी भी अलग-अलग हैं, ऑर्थोगोनल धारणाएं जिन्हें मिश्रित किया जा सकता है (यानी इनलाइन फ़ंक्शन टेम्पलेट)
पेरेसबल

इनकैप्सुलेशन टूट गया है? ऐसा कैसे? एन्कैप्सुलेशन आदमी (ओं) प्रोग्रामिंग के लिए है, स्मृति में वास्तविक वस्तुओं के लिए नहीं। उस बिंदु पर कोई परवाह नहीं करता है। यहां तक ​​कि अगर आप एक पुस्तकालय वितरित करते हैं, तो कंपाइलर इनलाइन को चुन सकता है या ऐसा करने के लिए नहीं है। इसलिए अंत में जब आप एक नया परिवाद प्राप्त करते हैं, तो आपको बस उस लाइब्रेरी से कार्यों और वस्तुओं का उपयोग करने वाले सभी चीजों को फिर से जोड़ना होगा।
FalcoGer

42

पुरातन सी और सी ++ में, inlineकी तरह है registerएक संभव अनुकूलन के बारे में संकलक के लिए एक सुझाव (एक सुझाव से ज्यादा कुछ नहीं):।

आधुनिक सी ++ में, inlineलिंकर को बताता है कि, यदि विभिन्न अनुवाद इकाइयों में कई परिभाषाएं (घोषणाएं नहीं) पाई जाती हैं, तो वे सभी समान हैं, और लिंकर स्वतंत्र रूप से एक को रख सकता है और अन्य सभी को त्याग सकता है।

inline यदि कोई फ़ंक्शन (चाहे कितना जटिल या "रैखिक") एक हेडर फ़ाइल में परिभाषित किया गया हो, तो कई स्रोतों को लिंकर द्वारा "एकाधिक परिभाषा" त्रुटि प्राप्त किए बिना इसे शामिल करने की अनुमति देना अनिवार्य है।

क्लास के अंदर परिभाषित सदस्य फ़ंक्शन डिफ़ॉल्ट रूप से "इनलाइन" होते हैं, जैसा कि टेम्पलेट फ़ंक्शन (वैश्विक कार्यों के विपरीत) हैं।

//fileA.h
inline void afunc()
{ std::cout << "this is afunc" << std::endl; }

//file1.cpp
#include "fileA.h"
void acall()
{ afunc(); }

//main.cpp
#include "fileA.h"
void acall();

int main()
{ 
   afunc(); 
   acall();
}

//output
this is afunc
this is afunc

FileA.h को दो। Cpp फ़ाइलों में शामिल करने पर ध्यान दें, जिसके परिणामस्वरूप दो उदाहरण हैं afunc()। लिंकर उनमें से एक को त्याग देगा। यदि कोई inlineनिर्दिष्ट नहीं है, तो लिंकर शिकायत करेगा।


16

इनलाइनर कंपाइलर को एक सुझाव है जिसे अनदेखा करना मुफ्त है। यह कोड के छोटे बिट्स के लिए आदर्श है।

यदि आपके फ़ंक्शन को इनलाइन किया गया है, तो यह मूल रूप से उस कोड में डाला जाता है, जहां फ़ंक्शन कॉल वास्तव में एक अलग फ़ंक्शन को कॉल करने के बजाय इसे बनाया जाता है। यह गति के साथ सहायता कर सकता है क्योंकि आपको वास्तविक कॉल नहीं करना है।

यह सीपीयू को पाइपलाइनिंग के साथ भी सहायता करता है क्योंकि उन्हें कॉल के कारण नए निर्देशों के साथ पाइपलाइन को फिर से लोड नहीं करना पड़ता है।

केवल नुकसान संभव है बाइनरी आकार में वृद्धि हुई है लेकिन, जब तक फ़ंक्शन छोटे होते हैं, यह बहुत ज्यादा मायने नहीं रखेगा।

मैं आजकल इस तरह के निर्णयों को संकलक तक छोड़ता हूं (खैर, वैसे भी स्मार्ट)। जिन लोगों ने उन्हें लिखा है उनमें अंतर्निहित आर्किटेक्चर का अधिक विस्तृत ज्ञान है।


12

इनलाइन फ़ंक्शन कंपाइलर्स द्वारा उपयोग की जाने वाली अनुकूलन तकनीक है। एक फ़ंक्शन इनलाइन बनाने के लिए प्रोटोटाइप को कार्य करने के लिए इनलाइन कीवर्ड को प्रीपेन्ड कर सकते हैं। इनलाइन फ़ंक्शन निर्देश संकलक को फ़ंक्शन का पूरा शरीर सम्मिलित करने का निर्देश देता है, जहां उस फ़ंक्शन को कोड में उपयोग किया जाता है।

लाभ: -

  1. इसे ओवरहेड कॉलिंग फ़ंक्शन की आवश्यकता नहीं है।

  2. यह फ़ंक्शन कॉलिंग के दौरान स्टैक पर चर पुश / पॉप के ओवरहेड को भी बचाता है।

  3. यह एक फ़ंक्शन से रिटर्न कॉल के ओवरहेड को भी बचाता है।

  4. यह निर्देश कैश का उपयोग करके संदर्भ की स्थानीयता को बढ़ाता है।

  5. इन-लाइनिंग कंपाइलर के बाद यदि निर्दिष्ट हो तो इंट्रा-प्रक्रियात्मक अनुकूलन भी लागू कर सकते हैं। यह सबसे महत्वपूर्ण है, इस तरह संकलक अब मृत कोड उन्मूलन पर ध्यान केंद्रित कर सकते हैं, शाखा भविष्यवाणी, प्रेरण चर उन्मूलन आदि पर अधिक तनाव दे सकते हैं।

इसके बारे में अधिक जानकारी के लिए कोई भी इस लिंक का अनुसरण कर सकता है http://tajendrasengar.blogspot.com/2010/03/what-is-inline-function-in-cc.html


4
1) यह एक सुझाव है, एक निर्देश 2) यह कोड आकार में वृद्धि की वजह से अधिक कैश छूट जाए पैदा कर सकता है अगर एक आमतौर पर इस्तेमाल किया समारोह एक बहुत inlined है
Flexo

3
क्या लिंक आपके व्यक्तिगत ब्लॉग के अंत में है? यदि यह है तो आपको इसे इस तरह से घोषित करना चाहिए, अन्यथा यह स्पैम की तरह दिखता है।
फ्लेक्सो

6

जब आप साझा लाइब्रेरी का निर्माण कर रहे हैं, तो मुझे लगता है कि इनलाइन फ़ंक्शन महत्वपूर्ण हैं। फ़ंक्शन इनलाइन को चिह्नित किए बिना, इसे बाइनरी रूप में लाइब्रेरी में निर्यात किया जाएगा। यदि निर्यात किया जाता है, तो यह प्रतीक तालिका में भी मौजूद होगा। दूसरी तरफ, इनबिल्ड फ़ंक्शंस का निर्यात नहीं किया जाता है, न तो लाइब्रेरी बायनेरीज़ और न ही प्रतीकों तालिका के लिए।

यह महत्वपूर्ण हो सकता है जब पुस्तकालय को रनटाइम पर लोड करने का इरादा हो। यह द्विआधारी-संगत-जागरूक पुस्तकालयों से भी टकरा सकता है। ऐसे मामलों में इनलाइन का उपयोग न करें।


@ जॉनसनवीब: मेरे उत्तर को ध्यान से पढ़ें। आपने जो कहा है वह सच है, जब आप एक निष्पादन योग्य निर्माण कर रहे हैं। लेकिन संकलक inlineएक साझा पुस्तकालय का निर्माण करते समय केवल उपेक्षा नहीं कर सकता है !
दस्तावेज़

4

अनुकूलन के दौरान कई कंपाइलर इनलाइन फ़ंक्शंस करेंगे भले ही आपने उन्हें चिह्नित नहीं किया हो। आपको आमतौर पर केवल इनलाइन के रूप में फ़ंक्शन को चिह्नित करने की आवश्यकता होती है यदि आपको पता है कि कुछ कंपाइलर नहीं है, क्योंकि यह आमतौर पर सही निर्णय खुद कर सकता है।


कई कंपाइलर भी ऐसा नहीं करेंगे, उदाहरण के लिए MSVC ऐसा तब तक नहीं करेगा जब तक आप इसे नहीं बताएंगे
paulm

4

inlineआपको हेडर फाइल में एक फंक्शन डेफिनिशन रखने की अनुमति देता है और #includeएक डेफिनेशन नियम का उल्लंघन किए बिना कई सोर्स फाइल्स में हेडर फाइल करता है।


3

सामान्यतया, किसी भी आधुनिक संकलक के साथ इन दिनों किसी भी चीज को बनाने की चिंता करना समय की बर्बादी है। संकलक को वास्तव में कोड के अपने विश्लेषण और संकलक को दिए गए अनुकूलन झंडे के आपके विनिर्देशन के माध्यम से आपके लिए इन सभी विचारों का अनुकूलन करना चाहिए। यदि आप गति की परवाह करते हैं, तो संकलक को गति के लिए अनुकूलन करने के लिए कहें। यदि आप अंतरिक्ष की परवाह करते हैं, तो संकलक को अंतरिक्ष के लिए अनुकूलन करने के लिए कहें। जैसा कि एक अन्य जवाब में कहा गया है, एक सभ्य संकलक भी इनलाइन स्वचालित रूप से अगर यह वास्तव में समझ में आता है।

साथ ही, जैसा कि दूसरों ने कहा है, इनलाइन का उपयोग किसी भी इनलाइन की गारंटी नहीं देता है। यदि आप इसकी गारंटी देना चाहते हैं, तो आपको इसे करने के लिए इनलाइन फ़ंक्शन के बजाय मैक्रो को परिभाषित करना होगा।

जब इनलाइन और / या समावेश को लागू करने के लिए मैक्रो को परिभाषित करते हैं? - केवल जब आपके पास कोड के एक महत्वपूर्ण खंड के लिए गति का प्रदर्शन और आवश्यक सिद्ध वृद्धि होती है, जिसे एप्लिकेशन के समग्र प्रदर्शन पर प्रभाव पड़ता है।


... यदि आप अंतरिक्ष के बारे में परवाह करते हैं, तो संकलक को अंतरिक्ष के लिए अनुकूलन करने के लिए कहें - गति के लिए अनुकूलन करने के लिए संकलक को कहने से सी ++ और सी के साथ छोटे बायनेरिज़ हो सकते हैं , इसी तरह, संकलक को अंतरिक्ष के लिए अनुकूलन करने के लिए कहने से तेज़ निष्पादन हो सकता है। iow, ये सुविधाएँ हमेशा विज्ञापन के रूप में काम नहीं करती हैं। इंसानों को अपने कार्यक्रम के कुछ पहलुओं को समझने की क्षमता होती है, जो संकलक की सामान्यीकृत व्याख्याओं से बेहतर होती है (जो कि हमें तेजी से बने रहना चाहिए)। मानव हस्तक्षेप एक बुरी बात नहीं है।
जस्टिन

3

यह प्रदर्शन के बारे में सब नहीं है। C ++ और C दोनों का उपयोग एम्बेडेड प्रोग्रामिंग के लिए किया जाता है, जो हार्डवेयर के शीर्ष पर बैठा होता है। यदि आप, उदाहरण के लिए, एक बाधा हैंडलर लिखते हैं, तो आपको यह सुनिश्चित करने की आवश्यकता है कि कोड को एक बार में निष्पादित किया जा सकता है, बिना अतिरिक्त रजिस्टर और / या मेमोरी पेजों को स्वैप किए बिना। जब इनलाइन काम में आती है। अच्छा संकलक कुछ "इनलाइनिंग" करता है जब गति की आवश्यकता होती है, लेकिन "इनलाइन" उन्हें मजबूर करता है।


1

इतने पुस्तकालयों में इनलाइनिंग कार्यों के साथ एक ही मुसीबत में फेल। ऐसा लगता है कि अंतर्निर्मित कार्यों को पुस्तकालय में संकलित नहीं किया गया है। परिणामस्वरूप लिंकर एक "अपरिभाषित संदर्भ" त्रुटि डालता है, यदि कोई निष्पादन योग्य लायब्रेरी के इनलाइन फ़ंक्शन का उपयोग करना चाहता है। (मुझे 4.5 क्यू के साथ क्यूटी स्रोत संकलन करने के लिए हुआ।


1

सभी फ़ंक्शन को डिफ़ॉल्ट रूप से इनलाइन क्यों नहीं किया जाता है? क्योंकि यह एक इंजीनियरिंग ट्रेड है। "अनुकूलन" के कम से कम दो प्रकार हैं: कार्यक्रम को गति देना और कार्यक्रम के आकार (मेमोरी पदचिह्न) को कम करना। Inlining आम तौर पर चीजों को गति देता है। यह फ़ंक्शन कॉल ओवरहेड से छुटकारा दिलाता है, फिर स्टैक से पैरामीटर खींचकर धक्का देने से बचता है। हालाँकि, यह प्रोग्राम के मेमोरी फ़ुटप्रिंट को भी बड़ा बनाता है, क्योंकि प्रत्येक फ़ंक्शन कॉल को अब फ़ंक्शन के पूर्ण कोड से बदला जाना चाहिए। चीजों को और अधिक जटिल बनाने के लिए, याद रखें कि सीपीयू स्टोर अल्ट्रा-फास्ट एक्सेस के लिए सीपीयू पर अक्सर कैश में मेमोरी का हिस्सा इस्तेमाल करते हैं। यदि आप प्रोग्राम की मेमोरी इमेज को काफी बड़ा कर देते हैं, तो आपका प्रोग्राम कैश का कुशलता से उपयोग नहीं कर पाएगा, और सबसे खराब स्थिति में इनलाइनिंग वास्तव में आपके प्रोग्राम को धीमा कर सकती है।


1

हमारे कंप्यूटर विज्ञान के प्रोफेसर ने हमें एक सी ++ प्रोग्राम में इनलाइन का उपयोग नहीं करने का आग्रह किया। यह पूछे जाने पर कि, उन्होंने हमें यह समझाया कि आधुनिक संकलक को पता लगाना चाहिए कि इनलाइन का उपयोग स्वचालित रूप से कब किया जाना चाहिए।

तो हाँ, इनलाइन जहाँ भी संभव हो उपयोग करने के लिए एक अनुकूलन तकनीक हो सकती है, लेकिन जाहिर है यह एक ऐसी चीज है जो आपके लिए पहले से ही हो जाती है जब भी किसी फ़ंक्शन को इनलाइन करना संभव होता है।


5
आपका प्रोफेसर दुर्भाग्य से पूरी तरह से गलत है। inlineC ++ में दो अलग-अलग अर्थ हैं - उनमें से केवल एक अनुकूलन से संबंधित है, और आपका प्रोफेसर उस संबंध में सही है। हालांकि, एक परिभाषा नियमinline को संतुष्ट करने के लिए दूसरा अर्थ अक्सर आवश्यक होता है ।
कोनराड रुडोल्फ

-1

एक और चर्चा से निष्कर्ष यहाँ:

क्या इनलाइन फ़ंक्शंस के साथ कोई कमियां हैं?

जाहिर है, इनलाइन फ़ंक्शन का उपयोग करने में कुछ भी गलत नहीं है।

लेकिन यह निम्नलिखित बिंदुओं पर ध्यान देने योग्य है!

  • इनलाइनिंग का अत्यधिक उपयोग वास्तव में कार्यक्रमों को धीमा कर सकता है। एक फ़ंक्शन के आकार के आधार पर, यह inlining कोड आकार को बढ़ाने या घटाने का कारण बन सकता है। एक बहुत छोटे एक्सेसर फ़ंक्शन को इनलाइन करना आमतौर पर कोड के आकार को कम करेगा जबकि एक बहुत बड़े फ़ंक्शन को सम्मिलित करते हुए नाटकीय रूप से कोड आकार को बढ़ा सकता है। आधुनिक प्रोसेसर पर छोटे कोड आमतौर पर निर्देश कैश के बेहतर उपयोग के कारण तेजी से चलते हैं। - Google दिशानिर्देश

  • इनलाइन फ़ंक्शंस की गति का लाभ कम हो जाता है क्योंकि फ़ंक्शन आकार में बढ़ता है। कुछ बिंदु पर फ़ंक्शन बॉडी के निष्पादन की तुलना में फ़ंक्शन कॉल का ओवरहेड छोटा हो जाता है, और लाभ खो जाता है - स्रोत

  • ऐसी कुछ स्थितियाँ हैं जहाँ कोई इनलाइन फ़ंक्शन काम नहीं कर सकता है:

    • मान लौटाने वाले फ़ंक्शन के लिए; यदि कोई रिटर्न स्टेटमेंट मौजूद है।
    • एक फ़ंक्शन के लिए कोई मान वापस नहीं; यदि कोई लूप, स्विच या गोटो स्टेटमेंट मौजूद है।
    • यदि कोई फ़ंक्शन पुनरावर्ती है। स्रोत
  • __inlineकीवर्ड एक समारोह केवल inlined जा करने के लिए यदि आप अनुकूलन विकल्प निर्दिष्ट कारण बनता है। यदि ऑप्टिमाइज़ निर्दिष्ट किया गया है, __inlineतो सम्मानित किया जाना है या नहीं , इनलाइन ऑप्टिमाइज़र विकल्प की सेटिंग पर निर्भर करता है। जब भी ऑप्टिमाइज़र चलाया जाता है, तो डिफ़ॉल्ट रूप से, इनलाइन विकल्प प्रभावी होता है। यदि आप ऑप्टिमाइज़ निर्दिष्ट करते हैं, तो यदि आप चाहते हैं कि __inlineकीवर्ड को अनदेखा किया जाए , तो आपको noinline विकल्प भी निर्दिष्ट करना होगा । स्रोत


3
सच होगा यदि इनलाइन एक कमांड थी और संकलक को संकेत नहीं। कंपाइलर वास्तव में क्या इनलाइन तय करता है।
मार्टिन यॉर्क

1
@LokiAstari मुझे पता है कि इनलाइन कंपाइलर के लिए अनुरोध है। मेरा तर्क यह है कि यदि कंपाइलर के लिए इसका संकेत है तो हमें यह तय करने के लिए कंपाइलर पर छोड़ देना चाहिए कि सबसे अच्छा क्या है। यदि आप इनलाइन का उपयोग करते हैं तो भी इनलाइन का उपयोग क्यों करें यह अभी भी संकलक है जो अंतिम निर्णय लेगा। मुझे आश्चर्य है कि मेरे Microsoft ने _forceinline पेश किया है।
कृष्ण ओझा

@krish_oza: मेरी टिप्पणी यहाँ। इस उत्तर के बारे में है। यहां जवाब पूरी तरह से गलत है। क्योंकि कंपाइलर यह निर्धारित करने के लिएinline कीवर्ड की अवहेलना करता है कि क्या इनलाइन कोड ऊपर दिए गए सभी बिंदु गलत हैं या नहीं । यदि कंपाइलर इनलाइनिंग के लिए कीवर्ड का उपयोग करता है (यह केवल लिंकिंग उद्देश्यों के लिए कई परिभाषाओं को निर्धारित करने के लिए उपयोग किया जाता है) तो वे सही होंगे।
मार्टिन यॉर्क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.