2015-01-21 7 views
5

मुझे दिलचस्पी है कि फंक्शन के रूप में नामित डिफ़ॉल्ट वैरिएबल को कैसे कार्यान्वित किया जाता है।फ़ंक्शन का डिफ़ॉल्ट रिटर्न वैरिएबल हमेशा आवंटित होता है?

  • क्या Sum हमेशा आवंटित है अगर मैं इसका उपयोग नहीं कर रहा हूं? (case 1 देखें)
  • यदि मैं में एक और चर (Total) चुनता हूं, तो इसका उपयोग Sum के बजाय किया जाता है?

निम्नलिखित 3 समकक्ष मामले भी संकलित किए जाने के बराबर हैं? या दूसरों के लिए कुछ बेहतर है?

' EQUIVALENT CASES 

' CASE 1 
Function Sum(a As Integer, b As Integer) As Integer 
    Return a + b 
End Function 

' CASE 2 
Function Sum(a As Integer, b As Integer) As Integer 
    Sum = a + b 
End Function 

' CASE 3 
Function Sum(a As Integer, b As Integer) As Integer 
    Dim Total As Integer 
    Total = a + b 
    Return Total 
End Function 

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

+0

मुझे लगता है कि कंपाइलर उन सभी तीनों को एक ही चीज़ बनाता है। केस 3 वैरिएबल बनाने में समय बर्बाद कर सकता है। – Keith

उत्तर

4

मैंने क्रमशः Sum1, Sum2, और Sum3 पर अपने कार्यों का नाम बदल दिया और फिर उन्हें लिंककैड के माध्यम से चलाया। यहां उत्पन्न आईएल:

Sum1: 
IL_0000: ldarg.1  
IL_0001: ldarg.2  
IL_0002: add.ovf  
IL_0003: ret   

Sum2: 
IL_0000: ldarg.1  
IL_0001: ldarg.2  
IL_0002: add.ovf  
IL_0003: stloc.0  // Sum2 
IL_0004: ldloc.0  // Sum2 
IL_0005: ret   

Sum3: 
IL_0000: ldarg.1  
IL_0001: ldarg.2  
IL_0002: add.ovf  
IL_0003: stloc.1  // Total 
IL_0004: ldloc.1  // Total 
IL_0005: ret   

ऐसा प्रतीत होता है कि Sum2 और Sum3 एक ही आईएल में परिणाम देता है। Sum1 अधिक कुशल प्रतीत होता है क्योंकि यह ऑपरेटर का परिणाम सीधे स्टैक पर डालता है। दूसरों को स्थानीय चर में ढेर से परिणाम खींचना चाहिए और फिर इसे वापस ढेर पर धक्का देना चाहिए!

+0

यह देखने के लिए बहुत दिलचस्प है कि कंपाइलर उन्हें अनुकूलित नहीं करता है, खासकर केस 2। मुझे खुशी है कि मैं हमेशा केस 1 का उपयोग करता हूं, उन नैनोसेकंड को बचाता हूं! : पी – Keith

+0

@ केथ - यह आईएल लिंककैड से आता है। यह संभव है कि जब रिलीज मोड में वीएस द्वारा संकलित किया गया हो या जब JITted किया जाए, तो यह सुझाव दिया जा सकता है कि आप अनुकूलित कर सकते हैं। –

+0

@ किथ - यह न केवल परिवर्तनीय सृजन के बारे में हो सकता है, बल्कि इनलाइनिंग के बारे में भी हो सकता है। फुकनशन का शरीर इनलाइन डाला गया है या स्टैक पर पैरामीटर डालने और उन सभी चीजों को रखने के साथ नियमित कॉल किया गया है ... – miroxlav

2

मैं वीबीएनईटी विशेषज्ञ नहीं हूं, लेकिन मुझे सी # के बारे में कुछ पता है। सी # में, इस तरह के कोड की अनुमति नहीं है। आपको हमेशा return एक मान होना चाहिए, अन्यथा कोड संकलित नहीं होगा।

मुझे लगता है कि VB.NET सी # में कुछ इस तरह से इस गतिरोध उत्पन्न:

T Sum = default(T); 

... 

return Sum; 

यह चूक Sum का मूल्य है, जो एक int के मामले में 0 है।

इस तर्क के अनुसार, परिवर्तनीय आवंटित किया जाता है, संदर्भ प्रकारों के लिए, इसका मतलब है कि कोई आवंटन नहीं होगा, क्योंकि उन्हें null पर डिफॉल्ट किया गया है। इस Function से

.method public static int32 Test() cil managed 
{ 
    // Code size  3 (0x3) 
    .maxstack 1 
    .locals init ([0] int32 Test) 
    IL_0000: nop 
    IL_0001: ldloc.0 
    IL_0002: ret 
} // end of method Module1::Test 

:

आईएल को देखते हुए

Function Test() As Integer 

End Function 

आप init है, जो एक चर (यह आवंटित करती है) और ldloc है, जो एक कॉल प्राप्त करने के लिए आरंभ देखेंगे एक चर के मूल्य, इसलिए, यह आवंटित किया जाना चाहिए।

+1

मुझे पता है कि। यही कारण है कि मैंने इस सवाल को टैग किया है ** vb.net **, न सिर्फ **। नेट ** या ** सी # **। – miroxlav

+0

आपका क्या मतलब है। तुम क्या जानते हो? –

+1

मैंने टिप्पणी की जब जवाब केवल सी # के बारे में था। यही कारण है कि मैंने शुरुआत में इसे कम कर दिया। अगर हम वीबी में रह सकते हैं तो मुझे खुशी होगी क्योंकि सी # और वीबी कंपाइलर इन मामलों में दृष्टिकोण पर पूरी तरह अलग हो सकते हैं। इसके अलावा, सी # 'केस 2' का समर्थन नहीं करता है। यदि आप कर सकते हैं, तो कृपया उत्तर के सी # भाग को हटा दें। – miroxlav

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

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