C # कंपाइलर ही उत्सर्जित IL को रिलीज़ बिल्ड में बहुत अधिक परिवर्तन नहीं करता है। उल्लेखनीय यह है कि यह अब एनओपी ऑपकोड का उत्सर्जन नहीं करता है जो आपको घुंघराले ब्रेस पर ब्रेकपॉइंट सेट करने की अनुमति देता है। बड़ा एक वह अनुकूलक है जो JIT संकलक में बनाया गया है। मुझे पता है कि यह निम्नलिखित अनुकूलन करता है:
विधि inlining। एक विधि कॉल को विधि के कोड को इंजेक्ट करके बदल दिया जाता है। यह एक बड़ा है, यह संपत्ति के उपयोगकर्ताओं को अनिवार्य रूप से मुक्त बनाता है।
सीपीयू रजिस्टर आवंटन। स्थानीय चर और विधि तर्क स्टैक फ्रेम में वापस संग्रहीत किए जा रहे बिना (या कम बार) सीपीयू रजिस्टर में संग्रहीत किए जा सकते हैं। यह एक बड़ा एक है, डिबगिंग अनुकूलित कोड को इतना मुश्किल बनाने के लिए उल्लेखनीय है। और वाष्पशील खोजशब्द को एक अर्थ देता है।
ऐरे इंडेक्स चेकिंग एलिमिनेशन। सरणियों के साथ काम करते समय एक महत्वपूर्ण अनुकूलन (सभी .NET संग्रह कक्षाएं आंतरिक रूप से एक सरणी का उपयोग करती हैं)। जब JIT कंपाइलर यह सत्यापित कर सकता है कि एक लूप कभी भी किसी सरणी को सीमा से बाहर नहीं करता है तो यह इंडेक्स चेक को समाप्त कर देगा। बड़ा वाला।
लूप का अनियंत्रित होना। शरीर में 4 गुना तक कोड को दोहराने और कम लूपिंग के साथ छोटे शरीर के साथ लूप में सुधार होता है। शाखा की लागत को कम करता है और प्रोसेसर के सुपर-स्केलर निष्पादन विकल्पों में सुधार करता है।
मृत कोड उन्मूलन। यदि (असत्य) {/ ... /} जैसा कथन पूरी तरह समाप्त हो जाता है। यह लगातार तह और inlining के कारण हो सकता है। अन्य मामले हैं जहां जेआईटी संकलक यह निर्धारित कर सकता है कि कोड का कोई संभावित दुष्प्रभाव नहीं है। यह अनुकूलन वह है जो प्रोफाइलिंग कोड को इतना मुश्किल बना देता है।
कोड फहराना। एक लूप के अंदर कोड जो लूप से प्रभावित नहीं होता है उसे लूप से बाहर ले जाया जा सकता है। सी कंपाइलर का आशावादी फहराने के अवसर खोजने में बहुत अधिक समय खर्च करेगा। हालांकि यह आवश्यक डेटा प्रवाह विश्लेषण के कारण एक महंगा अनुकूलन है और घबराना समय को बर्दाश्त नहीं कर सकता है इसलिए केवल स्पष्ट मामलों को लहराता है। .NET प्रोग्रामर को मजबूर करने के लिए बेहतर स्रोत कोड लिखने और खुद को फहराने के लिए।
सामान्य उप-अभिव्यक्ति उन्मूलन। x = y + 4; z = y + 4; z = x बन जाता है; भाग्य [ix + 1] = src [ix + 1] जैसे बयानों में बहुत आम है; सहायक चर को पेश किए बिना पठनीयता के लिए लिखा गया है। पठनीयता से समझौता करने की आवश्यकता नहीं है।
लगातार तह। x = 1 + 2; x = 3 हो जाता है; यह सरल उदाहरण संकलक द्वारा जल्दी पकड़ा जाता है, लेकिन जेआईटी समय पर होता है जब अन्य अनुकूलन यह संभव बनाते हैं।
प्रचार प्रसार की प्रति। x = ए; y = x; y = a; इससे रजिस्टर आवंटनकर्ता को बेहतर निर्णय लेने में मदद मिलती है। यह x86 के घबराने में एक बड़ी बात है क्योंकि इसमें काम करने के लिए बहुत कम रजिस्टर हैं। यह सही का चयन करने के लिए सही करने के लिए महत्वपूर्ण है।
ये बहुत ही महत्वपूर्ण अनुकूलन है कि एक बना सकते हैं महान , उदाहरण के लिए, आप अपने ऐप की डीबग बिल्ड प्रोफ़ाइल और यह रिलीज निर्माण की तुलना अंतर का सौदा। यह केवल वास्तव में मायने रखता है जब कोड आपके महत्वपूर्ण पथ पर होता है, तो कोड का 5 से 10% आप वास्तव में लिखते हैं में आपके कार्यक्रम की पूर्णता को प्रभावित करता है। JIT ऑप्टिमाइज़र सामने वाले को यह जानने के लिए पर्याप्त स्मार्ट नहीं है कि क्या महत्वपूर्ण है, यह केवल सभी कोड के लिए "इसे ग्यारह में बदल दें" डायल लागू कर सकता है।
आपके कार्यक्रम के निष्पादन समय पर इन अनुकूलन के प्रभावी परिणाम अक्सर कोड से प्रभावित होते हैं जो कहीं और चलता है। एक फ़ाइल पढ़ना, एक dbase क्वेरी निष्पादित करना, आदि कार्य को JIT ऑप्टिमाइज़र बनाना पूरी तरह से अदृश्य है। हालांकि यह बुरा नहीं है :)
JIT ऑप्टिमाइज़र बहुत विश्वसनीय कोड है, ज्यादातर क्योंकि यह लाखों बार परीक्षण के लिए रखा गया है। आपके प्रोग्राम के रिलीज़ बिल्ड संस्करण में समस्याएँ होना अत्यंत दुर्लभ है। हालांकि ऐसा होता है। दोनों x64 और x86 जिटर्स को स्ट्रक्चर्स की समस्या थी। X86 घबराहट में फ़्लोटिंग पॉइंट सुसंगतता के साथ परेशानी होती है, जब एक फ्लोटिंग पॉइंट गणना के मध्यवर्ती को एफपीयू रजिस्टर में 80-बिट परिशुद्धता पर रखा जाता है, जब मेमोरी को फ्लश किया जाता है, तब अलग-अलग परिणाम मिलते हैं।