2010-10-13 15 views
31

मैं समझने के लिए कि वास्तव में इसका मतलब है की कोशिश कर रहा है:विधि इनलाइनिंग क्या है?

इनलाइन समारोह

सी ++, एक सदस्य समारोह वर्ग घोषणा में परिभाषित किया। (2) एक फ़ंक्शन कॉल करें कि संकलक फ़ंक्शन के लिए वास्तविक कोड के साथ प्रतिस्थापित करता है। कीवर्ड इनलाइन का उपयोग किसी सदस्य के गैर-कार्य फ़ंक्शन के इनलाइन निष्पादन करने के लिए संकलक को संकेत देने के लिए किया जा सकता है।

इनलाइन

संकलन के दौरान समारोह के कोड की एक प्रति के साथ एक समारोह कॉल प्रतिस्थापित करने के लिए।

जब एक विधि अंतिम है, यह inlined हो सकता है:

उदाहरण के लिए यह कुछ ऐसा लिखा है।

यहाँ: http://www.roseindia.net/javatutorials/final_methods.shtml

तुम मुझे एक उदाहरण या कुछ दे सकते हैं या मूल रूप से मुझे समझने की क्या "यह inlined किया जा सकता है" का अर्थ है मदद करते हैं।

धन्यवाद।

+1

यह मददगार होगा: http://java.sun.com/developer/onlineTraining/Programming/JDCBook/perf2.html#vm – codaddict

उत्तर

49

इनलाइनिंग जावा जस्ट-इन-टाइम कंपाइलर द्वारा निष्पादित एक अनुकूलन है।

आप एक विधि है:

public int addPlusOne(int a, int b) { 
    return a + b + 1; 
} 

जो आप इस तरह कहते हैं:

public void testAddPlusOne() { 
    int v1 = addPlusOne(2, 5); 
    int v2 = addPlusOne(7, 13); 

    // do something with v1, v2 
} 

संकलक समारोह के शरीर के साथ अपने कार्य कॉल को बदलने के लिए तय कर सकते हैं, तो परिणाम होगा प्रभावी रूप से इस तरह दिखें:

public void testAddPlusOne() { 
    int v1 = 2 + 5 + 1; 
    int v2 = 7 + 13 + 1 

    // do something with v1, v2 
} 

कंपाइलर ओवरहेड ओ को बचाने के लिए करता है वास्तव में एक फ़ंक्शन कॉल कर रहा है, जिसमें प्रत्येक पैरामीटर को ढेर पर धक्का देना शामिल होगा।

यह स्पष्ट रूप से केवल गैर वर्चुअल फ़ंक्शंस के लिए किया जा सकता है। गौर करें कि क्या होगा यदि विधि उप वर्ग में ओवरराइड हो गई थी और विधि युक्त ऑब्जेक्ट का प्रकार रनटाइम तक ज्ञात नहीं है ... संकलक को कैसे पता चलेगा कि कौन सा कोड कॉपी करना है: बेस क्लास का विधि निकाय या उप वर्ग विधि शरीर? चूंकि जावा में डिफ़ॉल्ट रूप से सभी विधियां आभासी हैं, इसलिए आप उन लोगों को स्पष्ट रूप से चिह्नित कर सकते हैं जिन्हें final (या उन्हें final कक्षा में डाल दिया गया है) के रूप में ओवरराइड नहीं किया जा सकता है। यह संकलक को यह समझने में मदद करेगा कि विधि कभी खत्म नहीं होगी, और यह इनलाइन करने के लिए सुरक्षित है। (ध्यान दें कि संकलक कभी-कभी गैर-अंतिम तरीकों के लिए भी यह दृढ़ संकल्प कर सकता है।)

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

लाभ और समस्याओं के अच्छे अवलोकन के लिए wikipedia देखें।

+10

अच्छा जवाब, लेकिन एक नोट के रूप में: यदि आपके पास एक गैर-अंतिम विधि है जिसे आप * ओवरराइड नहीं करते हैं, तो एक अच्छा जेआईटी इसे समझ सकता है और वैसे भी इनलाइन कर सकता है। यदि आप उस वर्ग को लोड करते हैं जो इसे ओवरराइड करता है, तो यह इनलाइनिंग को पूर्ववत कर सकता है। – naiad

+0

अच्छा बिंदु, मैंने इसे उत्तर निकाय में जोड़ा। –

+0

यह बहुत ही व्याख्यात्मक है, इस महान उत्तर के लिए धन्यवाद। – Tarik

9

मान लीजिए कि आप एक वर्ग है कि इस तरह दिखता है दो:

public class Demo { 
    public void method() { 
     // call printMessage 
     printMessage(); 
    } 

    public void printMessage() { 
     System.out.println("Hello World"); 
    } 
} 

printMessage करने के लिए कॉल "inlined" किया जा सकता है निम्नलिखित तरीके से:

public class Demo { 
    public void method() { 
     // call printMessage 
     System.out.println("Hello World"); // <-- inlined 
    } 

    public void printMessage() { 
     System.out.println("Hello World"); 
    } 
} 

(यह वास्तव में पर नहीं किया जाता है जावा का स्तर (बाइटकोड स्तर पर भी नहीं) लेकिन जेआईटी-संकलन के दौरान, लेकिन ऊपर दिया गया उदाहरण इनलाइनिंग की अवधारणा को दर्शाता है।)

अब विचार करें कि क्या होगा printMessage विधि अन्य वर्ग, इस तरह से अतिभारित गया था:

class SubDemo extends Demo { 
    public void printMessage() { 
     System.out.println("Something else"); 
    } 
} 

संकलक यह System.out.println("Hello World"); के साथ फंस किया जाएगा Demo.printMessage करने के लिए कॉल जो मामले वस्तु वास्तव में एक था में गलत होगा inlined अब अगर SubDemo का उदाहरण।

हालांकि, अगर विधि घोषित की गई थी final यह किसी भी परिस्थिति में मामला नहीं होगा। यदि विधि "अंतिम" है तो इसका मतलब है कि इसे कभी भी नई परिभाषा से ओवरराइड नहीं किया जा सकता है, इस प्रकार, इसे इनलाइन करना सुरक्षित है!

+0

भी अच्छा जवाब है, लेकिन एक अन्य उत्तर से कॉपी की गई एक नोट के रूप में: यदि आपके पास गैर-अंतिम विधि जिसे आप ओवरराइड नहीं करते हैं, एक अच्छा जेआईटी इसे समझ सकता है और वैसे भी इनलाइन कर सकता है। यदि आप उस वर्ग को लोड करते हैं जो इसे ओवरराइड करता है, तो यह इनलाइनिंग को पूर्ववत कर सकता है। – naiad

+0

यह बहुत ही व्याख्यात्मक है, इस महान उत्तर के लिए धन्यवाद। – Tarik

10

फ़ंक्शन को कॉल करना मुफ़्त नहीं है। मशीन को एक स्टैक फ्रेम बनाए रखना चाहिए ताकि कॉल किए गए फ़ंक्शन को पूरा होने पर यह कोड के कॉलिंग सेक्शन पर वापस जा सके। ढेर को बनाए रखना (इस ढेर पर गुजरने वाले फ़ंक्शन पैरामीटर सहित) समय लगता है।

जब कोई फ़ंक्शन इन-लाइन होता है, तो कंपाइलर फ़ंक्शन के कोड के साथ कॉल को फ़ंक्शन पर बदल देता है ताकि कोई रन-टाइम पर फ़ंक्शन कॉल के प्रदर्शन दंड से बच सके। यह प्रोग्रामिंग में क्लासिक ट्रेड-ऑफ़ में से एक है: रन-टाइम कोड थोड़ा बड़ा हो जाता है (अधिक मेमोरी लेता है), लेकिन यह थोड़ा तेज़ चलता है।

+0

धन्यवाद। पहले अनुच्छेद में, आप वास्तव में सही हैं। – Tarik

संबंधित मुद्दे