डिबग और रिलीज़ बिल्ड के बीच प्रदर्शन अंतर


280

मुझे स्वीकार करना चाहिए, कि आमतौर पर मैंने अपने प्रोग्राम में डिबग और रिलीज़ कॉन्फ़िगरेशन के बीच स्विच करने की जहमत नहीं उठाई है , और मैंने आमतौर पर डिबग कॉन्फ़िगरेशन के लिए जाने का विकल्प चुना है , तब भी जब प्रोग्राम वास्तव में ग्राहकों के स्थान पर तैनात होते हैं।

जहाँ तक मुझे पता है, यदि आप इसे मैन्युअल रूप से नहीं बदलते हैं तो इन विन्यासों के बीच एकमात्र अंतर यह है कि डिबग को DEBUGनिरंतर परिभाषित किया गया है, और रिलीज़ में ऑप्टिमाइज़ कोड की जाँच की गई है।

तो मेरे सवाल वास्तव में दुगना है:

  1. क्या इन दोनों विन्यासों के बीच बहुत अधिक अंतर हैं। क्या कोई विशिष्ट प्रकार का कोड है जो यहां प्रदर्शन में बड़ा अंतर पैदा करेगा, या यह वास्तव में महत्वपूर्ण नहीं है?

  2. क्या कोई ऐसा कोड है जो डिबग कॉन्फ़िगरेशन के तहत ठीक चलेगा, जो रिलीज़ कॉन्फ़िगरेशन के तहत विफल हो सकता है, या क्या आप निश्चित हैं कि उस कोड का परीक्षण किया जा सकता है और उसके तहत ठीक काम कर रहा है डीबग कॉन्फ़िगरेशन के रिलीज़ कॉन्फ़िगरेशन के तहत भी ठीक काम करेगा।


जवाबों:


511

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-बिट परिशुद्धता पर रखा जाता है, जब मेमोरी को फ्लश किया जाता है, तब अलग-अलग परिणाम मिलते हैं।


23
मुझे नहीं लगता कि सभी संग्रह सरणी (नों) का उपयोग करते हैं: LinkedList<T>हालांकि, इसका उपयोग बहुत बार नहीं किया जाता है।
svick

मुझे लगता है कि सीएलआर एफपीयू को 53-बिट परिशुद्धता (64-बिट वाइड डबल्स से मेल खाते हुए) को कॉन्फ़िगर करता है, इसलिए फ्लोट64 मूल्यों के लिए 80-बिट विस्तारित डबल गणना नहीं होनी चाहिए। हालाँकि, इस 53-बिट सटीकता पर फ़्लोट 32 की गणना की जा सकती है और स्मृति में संग्रहीत होने पर केवल छंटनी की जाती है।
शासन

2
volatileकीवर्ड एक ढेर फ्रेम में संग्रहीत स्थानीय चर पर लागू नहीं होता। Msdn.microsoft.com/en-us/library/x13ttww7.aspx पर प्रलेखन से : "अस्थिर कीवर्ड केवल एक वर्ग या संरचना के क्षेत्रों पर लागू किया जा सकता है। स्थानीय चर अस्थिर नहीं घोषित किए जा सकते।"
क्रिस वैंडरमेन

8
एक विनम्र संशोधन के रूप में, मुझे लगता है कि वास्तव में क्या फर्क पड़ता है Debugऔर Releaseइस संबंध में बनाता है "कोड ऑप्टिमाइज़ करें" चेकबॉक्स है जो सामान्य रूप से के लिए Releaseपर है Debug। यह सिर्फ यह सुनिश्चित करने के लिए है कि पाठक यह न सोचें कि "जादू" है, दो बिल्ड कॉन्फ़िगरेशनों के बीच अदृश्य अंतर जो विज़ुअल स्टूडियो में प्रोजेक्ट प्रॉपर्टी पेज पर पाए जाने वाले से परे हैं।
चिक्कोडोरो

3
शायद उल्लेखनीय है कि System.Diagnostics.Debug पर लगभग कोई भी विधि डिबग बिल्ड में कुछ भी नहीं करती है। इसके अलावा चर बहुत जल्दी अंतिम रूप नहीं देते हैं (देखें stackoverflow.com/a/7165380/20553 )।
मार्टिन ब्राउन

23
  1. हां, कई प्रदर्शन अंतर हैं और ये वास्तव में आपके कोड पर लागू होते हैं। डीबग बहुत कम प्रदर्शन अनुकूलन करता है, और मोड बहुत जारी करता है;

  2. केवल कोड जो DEBUGनिरंतर पर निर्भर करता है एक रिलीज बिल्ड के साथ अलग-अलग प्रदर्शन कर सकता है। इसके अलावा, आपको कोई समस्या नहीं दिखनी चाहिए।

फ्रेमवर्क कोड का एक उदाहरण जो DEBUGनिरंतर पर निर्भर करता है वह Debug.Assert()विधि है, जिसमें विशेषता [Conditional("DEBUG)"]परिभाषित होती है। इसका मतलब यह है कि यह DEBUGनिरंतर पर भी निर्भर करता है और यह रिलीज बिल्ड में शामिल नहीं है।


2
यह सब सच है, लेकिन क्या आप कभी अंतर को माप सकते हैं? या एक कार्यक्रम का उपयोग करते समय एक अंतर नोटिस? बेशक, मैं किसी को अपने सॉफ्टवेयर को डिबग मोड में जारी करने के लिए प्रोत्साहित नहीं करना चाहता, लेकिन सवाल यह था कि अगर बहुत बड़ा प्रदर्शन अंतर है और मैं ऐसा नहीं कर सकता।
टेस्टालिनो

2
यह भी ध्यान देने योग्य है कि डिबग संस्करण मूल स्रोत कोड से रिलीज़ संस्करणों की तुलना में बहुत अधिक डिग्री तक सहसंबंधित हैं। यदि आपको लगता है कि (हालांकि संभावना नहीं है) कि कोई आपके निष्पादनयोग्य को रिवर्स-इंजीनियर करने की कोशिश कर सकता है, तो आप डिबग संस्करणों को तैनात करके उन पर इसे आसान नहीं बनाना चाहते हैं।
जेवरॉन

2
@testalino - खैर, इन दिनों यह मुश्किल है। प्रोसेसर ने यह तेजी से प्राप्त किया है कि उपयोगकर्ता शायद ही किसी प्रक्रिया के लिए प्रतीक्षा करता है क्योंकि उपयोगकर्ता कार्रवाई के कारण कोड निष्पादित करता है, इसलिए यह सब सापेक्ष है। हालाँकि, यदि आप वास्तव में कुछ लंबी प्रक्रिया कर रहे हैं, तो हाँ आप ध्यान देंगे। निम्नलिखित कोड जैसे 40% धीमी चलाता है के तहत DEBUG: AppDomain.CurrentDomain.GetAssemblies().Sum(p => p.GetTypes().Sum(p1 => p1.GetProperties().Length))
पीटर वैन गिन्केल

2
इसके अलावा, यदि आप जारी हैं asp.netऔर रिलीज के बजाय डिबग का उपयोग करते हैं, तो कुछ स्क्रिप्ट्स आपके पेज पर जोड़ी जा सकती हैं, जैसे: MicrosoftAjax.debug.jsजिसमें लगभग 7k लाइनें हैं।
ब्रूनोएलएम

13

यह बहुत हद तक आपके आवेदन की प्रकृति पर निर्भर करता है। यदि आपका एप्लिकेशन UI-भारी है, तो संभवतः आपको कोई अंतर दिखाई नहीं देगा क्योंकि आधुनिक कंप्यूटर से जुड़ा सबसे धीमा घटक उपयोगकर्ता है। यदि आप कुछ UI एनिमेशन का उपयोग करते हैं, तो आप परीक्षण कर सकते हैं कि क्या आप DEBUG बिल्ड में चलने के दौरान कोई ध्यान देने योग्य अंतराल महसूस कर सकते हैं।

हालांकि, यदि आपके पास कई संगणना-भारी गणनाएं हैं, तो आप अंतरों को नोटिस करेंगे (@Pieter के रूप में 40% तक अधिक हो सकता है, हालांकि यह गणनाओं की प्रकृति पर निर्भर करेगा)।

यह मूल रूप से एक डिज़ाइन ट्रेडऑफ़ है। यदि आप DEBUG बिल्ड के तहत जारी कर रहे हैं, तो यदि उपयोगकर्ता समस्याओं का अनुभव करते हैं, तो आप अधिक सार्थक ट्रेसबैक प्राप्त कर सकते हैं और आप बहुत अधिक लचीला निदान कर सकते हैं। DEBUG बिल्ड में रिलीज़ करके, आप अस्पष्ट हेइज़नबग्स का उत्पादन करने वाले ऑप्टिमाइज़र से भी बचते हैं ।


11
  • मेरा अनुभव यह रहा है कि मध्यम आकार या बड़े अनुप्रयोगों में रिलीज़ बिल्ड में अधिक उत्तरदायी होते हैं। इसे अपने आवेदन के साथ आज़माएं और देखें कि यह कैसा लगता है।

  • रिलीज बिल्ड के साथ एक चीज जो आपको काट सकती है वह यह है कि डिबग बिल्ड कोड कभी-कभी दौड़ की स्थिति और अन्य थ्रेडिंग से संबंधित बग को दबा सकता है। अनुकूलित कोड के परिणामस्वरूप अनुदेश पुन: व्यवस्थित हो सकता है और तेजी से निष्पादन कुछ दौड़ स्थितियों को तेज कर सकता है।


9

आपको कभी भी .NET डेबग बिल्ड को उत्पादन में जारी नहीं करना चाहिए। इसमें Edit-and-Continue या कौन और क्या जानता है, का समर्थन करने के लिए बदसूरत कोड हो सकता है। जहाँ तक मुझे पता है, यह केवल VB नहीं C # में होता है (ध्यान दें: मूल पोस्ट को C # टैग किया गया है) , लेकिन इसे अभी भी रुकना चाहिए क्योंकि Microsoft को लगता है कि उन्हें डीबग बिल्ड के साथ करने की अनुमति है। वास्तव में, .NET 4.0 से पहले, VB कोड उन मेमोरी की संख्या के लिए आनुपातिक लीक करता है, जो आपके द्वारा एडिट-एंड-कंटिन्यू के समर्थन में निर्मित घटनाओं के साथ होती हैं। (हालांकि यह प्रति-फिक्स्ड https://connect.microsoft.com/VisualStudio/feedback/details/481671/vb-classes-with-events-are-not-garbage-collected-when-debugging , तय कोड के अनुसार तय होने की सूचना है बुरा लग रहा है, WeakReferenceवस्तुओं का निर्माण और उन्हें स्थिर सूची में जोड़ते समयएक ताला पकड़े हुए ) मैं निश्चित रूप से उत्पादन वातावरण में इस तरह के डिबगिंग समर्थन नहीं चाहता!


मैंने कई बार डिबग बिल्ड रिलीज़ किया है, और कभी कोई समस्या नहीं देखी। एकमात्र अंतर शायद, यह है कि हमारा सर्वर साइड एप्लिकेशन बहुत सारे उपयोगकर्ताओं का समर्थन करने वाला वेब ऐप नहीं है। लेकिन यह बहुत अधिक प्रोसेसिंग लोड के साथ एक सर्वर साइड एप्लिकेशन है। मेरे अनुभव से डिबग और रिलीज़ के बीच का अंतर पूरी तरह से सैद्धांतिक लगता है। मैंने कभी भी हमारे किसी भी ऐप के साथ कोई व्यावहारिक अंतर नहीं देखा है।
सैम गोल्डबर्ग

5

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

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


अनुवर्ती कार्रवाई करने के लिए, यहां एक लेख जो एक रिलीज़ बग का उदाहरण देता है: codeproject.com/KB/trace/ReleaseBug.aspx
रोली

अभी भी इसकी एक समस्या है अगर आवेदन का परीक्षण किया जाता है और डिबग सेटिंग्स के साथ अनुमोदित किया जाता है, भले ही यह त्रुटियों को दबाए, अगर यह कारण बनता है कि रिलीज का निर्माण तैनाती के दौरान विफल हो जाता है।
10yvind Bråthen

4

मैं कहूंगा कि 1) काफी हद तक आपके कार्यान्वयन पर निर्भर करता है। आमतौर पर, अंतर इतना बड़ा नहीं होता है। मैंने बहुत सारे माप किए और अक्सर मैं अंतर नहीं देख सकता था। यदि आप अप्रबंधित कोड का उपयोग करते हैं, तो बहुत सारे विशाल सरणियों और सामान की तरह, प्रदर्शन अंतर थोड़ा बड़ा है, लेकिन एक अलग दुनिया नहीं है (जैसे C ++)। 2) आमतौर पर रिलीज़ कोड में कम त्रुटियों को दिखाया जाता है (उच्च सहिष्णुता), इसलिए एक स्विच को ठीक काम करना चाहिए।


1
IO बाउंड कोड के लिए, एक रिलीज़ बिल्ड आसानी से डिबग नहीं हो सकता है।
रिचर्ड

0
    **Debug Mode:**
    Developer use debug mode for debugging the web application on live/local server. Debug mode allow developers to break the execution of program using interrupt 3 and step through the code. Debug mode has below features:
   1) Less optimized code
   2) Some additional instructions are added to enable the developer to set a breakpoint on every source code line.
   3) More memory is used by the source code at runtime.
   4) Scripts & images downloaded by webresource.axd are not cached.
   5) It has big size, and runs slower.

    **Release Mode:**
    Developer use release mode for final deployment of source code on live server. Release mode dlls contain optimized code and it is for customers. Release mode has below features:
   1) More optimized code
   2) Some additional instructions are removed and developer cant set a breakpoint on every source code line.
   3) Less memory is used by the source code at runtime.
   4) Scripts & images downloaded by webresource.axd are cached.
   5) It has small size, and runs fast.

2
यह रिलीज़ मोड की तुलना में लगता है कभी-कभी किसी सूची के पहले तत्वों को सही ढंग से गिना नहीं जाता है। इसके अलावा सूची के भीतर कुछ तत्वों को दोहराया गया है। :)
जियान पाओलो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.