डीबग बनाम रिलीज़ प्रदर्शन


132

मैंने निम्नलिखित पैराग्राफ का सामना किया है:

"जब आप दृश्य स्टूडियो में अपना कोड संकलित करते हैं, तो IDE में डिबग बनाम रिलीज़ सेटिंग, प्रदर्शन के लिए लगभग कोई फर्क नहीं पड़ता ... उत्पन्न कोड लगभग समान है। C # कंपाइलर वास्तव में कोई अनुकूलन नहीं करता है। C # कंपाइलर सिर्फ IL… को बाहर निकालता है और रनटाइम पर यह JITer है जो सभी ऑप्टिमाइज़ेशन करता है। JITer में एक डिबग / रिलीज़ मोड है और इससे प्रदर्शन पर बहुत फर्क पड़ता है। लेकिन यह महत्वपूर्ण नहीं है कि आप अपने प्रोजेक्ट के डिबग या रिलीज़ कॉन्फ़िगरेशन को चलाते हैं या नहीं, कि कोई डिबगर संलग्न है या नहीं।

स्रोत यहाँ है और पॉडकास्ट यहाँ है

क्या कोई मुझे Microsoft लेख के लिए निर्देशित कर सकता है जो वास्तव में यह साबित कर सकता है?

Googling " C # डिबग बनाम रिलीज़ प्रदर्शन " अधिकतर यह कहते हुए परिणाम देता है कि " डीबग में बहुत अधिक प्रदर्शन हिट होता है ", " रिलीज़ अनुकूलित है ", और " डिबग को उत्पादन के लिए तैनात नहीं करते "।



Win7-x86 पर .Net4 के साथ, मेरे पास एक सीपीयू सीमित कार्यक्रम है जो मैंने लिखा है कि मुख्य लूप में कोई आरोही / आदि के साथ डिबग की तुलना में रिलीज़ में लगभग 2x तेजी से चलता है।
बेंगई

इसके अलावा, यदि आप मेमोरी के उपयोग की परवाह करते हैं, तो बड़े अंतर हो सकते हैं। मैंने एक ऐसा मामला देखा है, जहां डिबग मोड में संकलित एक बहु-थ्रेडेड विंडोज सेवा का उपयोग थ्रेड बिल्ड में बनाम प्रति थ्रेड के अनुसार 700 एमबी प्रति थ्रेड, बनाम 50 एमबी का उपयोग किया गया है। डीबग बिल्ड जल्दी से विशिष्ट उपयोग की शर्तों के तहत मेमोरी से बाहर भाग गया।
ओ। nate

@ बेंगी - क्या आपने सत्यापित किया है कि यदि आप एक डिबगर को रिलीज बिल्ड से जोड़ते हैं, तो यह अभी भी 2x तेजी से चलता है? ध्यान दें कि ऊपर दिया गया उद्धरण कहता है कि JIT अनुकूलन डिबगर संलग्न है या नहीं।
टूलमेकर

जवाबों:


99

आंशिक रूप से सच है। डीबग मोड में, कंपाइलर सभी चर के लिए डिबग प्रतीकों का उत्सर्जन करता है और जैसा है कोड को संकलित करता है। रिलीज़ मोड में, कुछ अनुकूलन शामिल हैं:

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

बाकी जेआईटी तक है।

अनुकूलन की पूर्ण सूची यहां के सौजन्य से एरिक Lippert


10
और Debug.Asserts के बारे में मत भूलना! DEBUG बिल्ड में, यदि वे विफल होते हैं, तो वे थ्रेड को रोक देंगे और एक संदेश बॉक्स पॉप अप करेंगे। रिहाई में वे बिल्कुल भी संकलित नहीं होते। यह उन सभी तरीकों के लिए लागू होता है जिनमें [ConditionalAttribute] है।
इवान ज़्लातनोव

13
सी # संकलक पूंछ कॉल अनुकूलन नहीं करता है; घबराना करता है। यदि आप ऑप्टिमाइज़ेशन स्विच चालू होने पर C # कंपाइलर क्या करते हैं, इसकी एक सटीक सूची चाहते हैं, तो blogs.msdn.com/ericlippert/archive/2009/06/11/…
Eric Lippert

63

कोई भी ऐसा लेख नहीं है जो किसी प्रदर्शन प्रश्न के बारे में कुछ भी "साबित" करता हो। किसी परिवर्तन के प्रदर्शन प्रभाव के बारे में दावा साबित करने का तरीका यह है कि इसे दोनों तरीकों से आज़माया जाए और इसे यथार्थवादी-लेकिन-नियंत्रित परिस्थितियों में परीक्षण किया जाए।

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

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

उस समय पर खर्च करें जब आप इस प्रश्न पर शोध करने के लिए एक उपकरण बनाने पर ऑनलाइन खर्च करते हैं जो प्रश्न का उत्तर देता है। आप इस तरह से कहीं अधिक सटीक परिणाम प्राप्त करेंगे। आप जो कुछ भी ऑनलाइन पढ़ते हैं वह सिर्फ एक अनुमान है कि क्या हो सकता है। आपके द्वारा एकत्र किए गए तथ्यों के कारण, अन्य लोगों के अनुमानों से नहीं कि आपका कार्यक्रम कैसा व्यवहार कर सकता है।


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

11

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


मैं उस मुद्दे पर आपसे सहमत हूं, लेकिन यह मुख्य प्रश्न का उत्तर नहीं देता है
sagie

5
@ सागी: हाँ, मुझे इस बारे में पता है लेकिन मुझे लगा कि बिंदु अभी भी बनाने लायक है।
कोनराड रुडोल्फ

6

से MSDN सामाजिक

यह अच्छी तरह से प्रलेखित नहीं है, यहाँ मुझे पता है। कंपाइलर System.Diagnostics.DebuggableAttribute की एक आवृत्ति का उत्सर्जन करता है। डीबग संस्करण में, IsJitOptimizerEnabled गुण सत्य है, रिलीज़ संस्करण में यह गलत है। आप इस विशेषता को ildasm.exe के साथ असेंबली मैनिफ़ेस्ट में देख सकते हैं

JIT संकलक इस विशेषता का उपयोग अनुकूलन को निष्क्रिय करने के लिए करता है जो डिबगिंग को कठिन बना देगा। जो कोड को लूप-इन्वारिएंट उत्थापन की तरह घुमाते हैं। चयनित मामलों में, यह प्रदर्शन में बड़ा बदलाव ला सकता है। हालांकि आमतौर पर नहीं।

ब्रेकपॉइंट्स को निष्पादन के पते पर मैप करना डीबगर का काम है। यह .pdb फ़ाइल और JIT संकलक द्वारा उत्पन्न जानकारी का उपयोग करता है जो कोड पता मानचित्रण के लिए IL निर्देश प्रदान करता है। यदि आप अपना डिबगर लिखते हैं, तो आप ICorDebugCode :: GetILToNativeMapping () का उपयोग करेंगे।

JIT कंपाइलर ऑप्टिमाइज़ेशन अक्षम होने के बाद मूल रूप से डिबग परिनियोजन धीमा हो जाएगा।


3

आपने जो पढ़ा है वह काफी मान्य है। रिलीज आमतौर पर JIT ऑप्टिमाइजेशन के कारण अधिक दुबला होता है, जिसमें डिबग कोड (#IF DEBUG या [कंडिशनल ("DEBUG")]) शामिल नहीं है, न्यूनतम डिबग प्रतीक लोडिंग और अक्सर माना नहीं जा रहा है जो छोटा असेंबली है जो लोडिंग समय को कम करेगा। अधिक व्यापक पीडीबी और लोड किए गए प्रतीकों के कारण VS में कोड चलाते समय प्रदर्शन भिन्न होना अधिक स्पष्ट है, लेकिन यदि आप इसे स्वतंत्र रूप से चलाते हैं, तो प्रदर्शन अंतर कम स्पष्ट हो सकते हैं। कुछ कोड अन्य की तुलना में बेहतर अनुकूलन करेंगे और यह अन्य भाषाओं की तरह ही अनुकूलन वाले अनुकूलन का उपयोग कर रहा है।

स्कॉट में इनलाइन विधि अनुकूलन पर एक अच्छी व्याख्या है

इस आलेख को देखें जो डीबग और रिलीज़ सेटिंग के लिए ASP.NET वातावरण में भिन्न क्यों है, इसका संक्षिप्त विवरण दें।


3

एक बात जो आपको ध्यान में रखनी चाहिए, प्रदर्शन के बारे में और क्या डिबगर जुड़ा हुआ है या नहीं, कुछ ऐसा है जो हमें आश्चर्यचकित करता है।

हमारे पास कोड का एक टुकड़ा था, जिसमें कई तंग लूप शामिल थे, जो हमेशा के लिए डिबग करने के लिए लग रहे थे, फिर भी अपने आप ही काफी अच्छी तरह से चले गए। दूसरे शब्दों में, कोई भी ग्राहक या ग्राहक जहां समस्याओं का सामना नहीं कर रहा है, लेकिन जब हम डिबगिंग कर रहे थे तो यह गुड़ की तरह चल रहा था।

अपराधी एक था Debug.WriteLine तंग छोरों में से एक , जो हजारों लॉग संदेशों को थूक देता है, थोड़ी देर पहले डिबग सत्र से छोड़ दिया जाता है। ऐसा लगता है कि जब डिबगर संलग्न होता है और ऐसे आउटपुट को सुनता है, तो ओवरहेड शामिल होता है जो प्रोग्राम को धीमा कर देता है। इस विशेष कोड के लिए, यह अपने आप में 0.2-0.3 सेकंड रनटाइम के क्रम पर था, और डिबगर संलग्न होने पर 30+ सेकंड।

सरल समाधान, हालांकि, उन डिबग संदेशों को हटा दें जिनकी अब आवश्यकता नहीं थी।


2

में MSDN साइट ...

रिलीज़ बनाम डिबग कॉन्फ़िगरेशन

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

जब आप अपने एप्लिकेशन को अंतिम उपयोगकर्ताओं के लिए वितरित करने के लिए तैयार होते हैं, तो एक रिलीज़ बिल्ड बनाएं, जो बहुत छोटा होगा और आमतौर पर संबंधित डिबग कॉन्फ़िगरेशन की तुलना में बहुत बेहतर प्रदर्शन होगा। आप बिल्ड कॉन्फ़िगरेशन प्रोजेक्ट डिज़ाइनर के बिल्ड फलक में या बिल्ड टूलबार में सेट कर सकते हैं। अधिक जानकारी के लिए, बिल्ड कॉन्फ़िगरेशन देखें।


1

काफी हद तक, यह इस बात पर निर्भर करता है कि आपका ऐप कंप्यूट-बाउंड है या नहीं, और यह बताना हमेशा आसान नहीं होता है, जैसा कि लेसे के उदाहरण में है। अगर मुझे थोड़ा सा सवाल है कि यह क्या कर रहा है, तो मैंने इसे कुछ बार रोक दिया और स्टैक की जांच की। अगर वहां कुछ अतिरिक्त चल रहा है, जिसकी मुझे वास्तव में जरूरत नहीं है, तो यह तुरंत ही हो जाता है।


1

मैं हाल ही में एक प्रदर्शन के मुद्दे पर भाग रहा हूं। उत्पादों की पूरी सूची में बहुत समय लग रहा था, लगभग 80 सेकंड। मैंने DB को ट्यून किया, प्रश्नों में सुधार किया और कोई अंतर नहीं आया। मैंने एक TestProject बनाने का निर्णय लिया और मुझे पता चला कि उसी प्रक्रिया को 4 सेकंड में निष्पादित किया गया था। तब मुझे एहसास हुआ कि परियोजना डिबग मोड में थी और परीक्षण परियोजना रिलीज़ मोड में थी। मैंने मुख्य परियोजना को रिलीज़ मोड में बदल दिया और सभी परिणामों को प्रदर्शित करने के लिए उत्पादों की पूरी सूची में केवल 4 सेकंड लगे।

सारांश: डिबग मोड रन मोड की तुलना में कहीं अधिक धीमा है क्योंकि यह डिबगिंग जानकारी रखता है। आपको हमेशा रिले मोड में तैनात करना चाहिए। यदि आप .PDB फ़ाइलों को शामिल करते हैं, तो भी आपके पास डिबगिंग जानकारी हो सकती है। इस तरह आप लाइन नंबरों के साथ त्रुटियों को लॉग इन कर सकते हैं, उदाहरण के लिए।


"रन मोड" से आपका मतलब "रिलीज़" है?
रॉन क्लिन

हाँ बिल्कुल। रिलीज में सभी डीबग ओवरहेड नहीं है।
फ्रांसिस्को गोल्डनस्टीन

1

डिबग और रिलीज़ मोड में अंतर है। एक उपकरण है Fuzzlyn : यह एक फ़ूज़र है जो रोसलिन का उपयोग यादृच्छिक सी # प्रोग्राम उत्पन्न करने के लिए करता है। यह इन कार्यक्रमों को .NET कोर पर चलाता है और यह सुनिश्चित करता है कि वे डिबग और रिलीज़ मोड में संकलित होने पर समान परिणाम दें।

इस उपकरण के साथ यह पाया गया और बहुत सारे बगों की सूचना दी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.