2012-02-02 14 views
7

तो सी # में, आपको निम्न कोड हो सकता है:सी # स्थानीय चरों को ऊपर की ओर क्यों बांधता है?

void DoSomething() 
{ 
    //some code. 
    int x = 5; 
    //some more code. 
} 

जैसे ही आप DoSomething प्रवेश के रूप में, CLR के लिए int x स्थान को निर्धारित करता है। यह तब तक इंतजार क्यों नहीं करता जब तक कि यह int x = 5 के साथ लाइन तक नहीं पहुंच जाता? खासकर जब से एक्स बाध्य है, यह आपको वास्तव में तब तक इसका उपयोग नहीं करने देता है जब तक कि उस लाइन तक पहुंच न जाए?

+8

स्टैक आकार को समायोजित करना क्यों बढ़ता जा रहा है, इसे सभी को आगे आरक्षित करने से बेहतर होगा? – ildjarn

+0

संभवतः, स्टैक के साथ गड़बड़ करने में कुछ समय लगता है ... अगर मेरे पास बहुत से स्थानीय चर हैं, तो मुझे तब तक इंतजार क्यों करें जब तक मुझे अभी तक (अभी तक) नहीं है? – GWLlosa

+2

ठीक है, इसमें स्टैक के साथ गड़बड़ करने में कुछ समय लगता है, इसलिए हर बार एक नए चर के दायरे में प्रवेश करने के बजाए इसे ऊपर और ऊपर की तरफ मोड़ना ठीक है। – ildjarn

उत्तर

13

जैसे ही आप DoSomething दर्ज करते हैं, सीएलआर int x के लिए स्थान सेट करता है। यह तब तक प्रतीक्षा क्यों नहीं करता जब तक कि यह int x = 5 पर लाइन तक पहुंच न जाए?

प्रश्न उत्तरदायी नहीं है क्योंकि पूरा प्रश्न गलत आधार पर स्थापित किया गया है। स्थानीय चर के लिए संग्रहण स्थान हो सकता है:

  • आवंटित जब विधि पहले दर्ज किया गया है
  • आवंटित जब नियंत्रण प्रारंभ पर पहुंच जाने पर नियंत्रण घोषणा
  • आवंटित तक पहुँच जाता है (यह मानते हुए प्रारंभ और घोषणा अलग हैं)
  • विशेष परिस्थितियों में आवंटित - यदि उदाहरण के लिए स्थानीय लैम्ब्डा का बंद-बंद स्थानीय है, या एइटरेटर ब्लॉक में है, या एसिंक ब्लॉक में, स्थानीय संग्रहण आवंटित कैसे और कब जटिल हो सकता है
  • elided पूरी तरह से; यदि स्थानीय का कभी भी उपयोग नहीं किया जाता है तो इसे पहले स्थान पर आवंटित नहीं किया जा सकता है।

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

चूंकि प्रश्न का आधार गलत है, इसलिए सवाल का कोई जवाब नहीं है। एक बेहतर सवाल पूछें।

+0

उत्तर है [mu] (http://bit.ly/s4jx85)। – jason

+1

10 अपवॉट्स और एक उत्तर के लिए एक स्वीकृति जो दावा करती है कि सवाल का कोई जवाब नहीं है। यह उत्तर मौजूदा रूप से विरोधाभास प्रतीत होता है। –

+2

@IgbyLargeman: जब आप उपरोक्त पर होवर करते हैं तो संकेत मिलता है "यह उत्तर उपयोगी है", नहीं "यह उत्तर पूछा गया था कि सवाल"। यदि यह इंगित करता है कि एक गलत आधार पर एक प्रश्न का अनुमान लगाया गया है * उपयोगी * तो वहां कोई विरोधाभास नहीं है। –

10

कि आप जानते होंगे, वहाँ मूल कोड सी # कोड से कई कदम हैं उन हैं:

  • सी # से आईएल (बाईटकोड)
  • बाईटकोड से मूल कोड को JITting के संकलन

सी # उस समय का कोई नियंत्रण नहीं है जब स्मृति आवंटित की जाती है, जिसे आप बाध्यकारी पर कॉल करते हैं, यह पूरी तरह से जेआईटी तक है। इसे देखने के तरीके से देखें कि सी # के नियंत्रण में है। सी # द्वारा उत्पादित बाइट कोड को CLR ECMA मानक का पालन करना होगा। यदि हम विभाजन 1 की धारा 12.1.6.1 पर जाते हैं, तो हम देखेंगे कि मानक परिभाषित करता है कि स्थानीय चर के घर विधि शीर्षलेख में है। चूंकि एक नियम के रूप में विधि हस्ताक्षर एक सूची में किसी विधि की शुरुआत में दिखाई देते हैं, इसलिए आपको एक (झूठी) इंप्रेशन मिलता है कि वे बाध्य अपफ्रंट हैं, जो वास्तव में मामला हो सकता है या नहीं भी हो सकता है।

यदि आप संकलित देशी कोड को देख रहे हैं, तो परिणाम प्लेटफ़ॉर्म से प्लेटफ़ॉर्म तक भिन्न हो सकता है। स्थानीय चर के लिए सीपीयू स्टैक पर ऐतिहासिक रूप से आवंटित स्थान को स्टैक पॉइंटर बदलने के एक सीपीयू निर्देश द्वारा किया जाता है। यदि आप इसे चर द्वारा परिवर्तनीय करना चाहते हैं तो आपके पास कई निर्देश, एक प्रति चर, जो कम कुशल है। यही कारण है कि, कम से कम x86 पर आप यह देखने जा रहे हैं कि सीपीयू स्टैक पर स्थान आवंटित किया गया है।

1

आपका प्रश्न में कुछ मान्यताओं के आधार पर लगता है:

  • सेटअप की लागत हमेशा उच्च
  • सेटअप केवल बार
  • संदर्भ की एक छोटी संख्या होने जा रहा है होने जा रहा है/सीएलआर स्तर पर मूल्य प्रकार हमेशा सी # स्तर

पर चर के साथ एक से एक मैपिंग है, यह आपके कोड के लिए सच हो सकता है लेकिन वहां अधिकांश कोड के लिए सच नहीं हो सकता है।

धारणाएं प्रक्रिया की अंतर्निहित परतों की उपस्थिति को अनदेखा करती हैं जो इसे मशीन कोड में संकलित/व्याख्या करती हैं।

संक्षेप में, सी # में जो कोड आप लिखते हैं वह एक अमूर्त है जो आईएल पर निर्भर करता है जो एक और अमूर्त है जो सीएलआर पर निर्भर करता है जो एक और अमूर्त है और इसी तरह।

इसके लायक होने के लिए, मुझे इस निर्णय के बारे में गंभीर संदेह है कि आपके आवेदन के प्रदर्शन पर महत्वपूर्ण प्रभाव पड़ता है ... लेकिन शायद एरिक लिपर्ट (http://blogs.msdn.com/b/ericlippert/) की तरह अधिक गहन विश्लेषण साझा कर सकते हैं।

3

संकलक क्या करना चाहिए अगर यह करने के लिए कुछ इसी तरह पाता है:

for (int i = 0; i < 1000; i++) 
{ 
    int j = .... //should the compiler set up space when it reaches this line? 1000 times? 
} 

इसके अलावा मैं वास्तव में लगता है कि स्थानीय लोगों की अंतरिक्ष की स्थापना की लागत एक कारक नहीं है। यदि ऐसा होता है तो आप शायद एक ही विधि में बहुत से स्थानीय लोगों से निपट रहे हैं और आप अपने कोड को दोबारा सुधारने से बेहतर हैं।

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