.NET के अपवाद कितने धीमे हैं?


143

मैं अपवादों को कब और कहां फेंकूं, इस बारे में चर्चा नहीं चाहता। मैं एक साधारण मुद्दे को हल करना चाहता हूं। उस समय का 99% अपवादों को न फेंकने का तर्क उनके आस-पास घूमता है, जबकि दूसरा पक्ष (बेंचमार्क टेस्ट के साथ) दावा करता है कि गति मुद्दा नहीं है। मैंने एक ओर या दूसरे से संबंधित कई ब्लॉग, लेख और पोस्ट पढ़े हैं। तो यह कौन सा है?

जवाब से कुछ लिंक: स्कीट , मरिअनी , ब्रूमे


13
झूठ हैं, झूठ हैं और बेंचमार्क हैं। :)
gbjbaanb

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

जवाबों:


207

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

बस इसे स्पष्ट करने के लिए - मैं उन अपवादों का उपयोग करने का समर्थन नहीं करता जहां वे तार्किक नहीं हैं। उदाहरण के लिए, int.TryParseउपयोगकर्ता से डेटा परिवर्तित करने के लिए पूरी तरह से उपयुक्त है। मशीन जनित फ़ाइल को पढ़ते समय यह उचित है, जहाँ विफलता का अर्थ है "फ़ाइल उस प्रारूप में नहीं है जिसका यह अर्थ है, मैं वास्तव में इसे संभालने की कोशिश नहीं करना चाहता क्योंकि मुझे नहीं पता कि और क्या गलत हो सकता है। "

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


2
दुर्भाग्य से, लोगों को बताया गया है कि अपवाद स्वतंत्र हैं, उन्हें तुच्छ 'सही' कार्यक्षमता के लिए उपयोग करें, उनका उपयोग तब किया जाना चाहिए जैसा कि आप कहते हैं, जब चीजें गलत हो
गईं

4
हां, लोगों को निश्चित रूप से पता होना चाहिए कि अनुचित तरीके से अपवादों का उपयोग करने से संबंधित प्रदर्शन लागत है। मुझे लगता है कि यह एक गैर-मुद्दा है जब उन्हें उचित रूप से उपयोग किया जाता है :)
जॉन स्कीट

7
@PaLLockwood: मैं कहूंगा कि यदि आपको प्रति सेकंड 200+ अपवाद मिले हैं, तो आप अपवादों को छोड़ रहे हैं। यह स्पष्ट रूप से एक "असाधारण" घटना नहीं है अगर यह प्रति सेकंड 200 बार हो रहा है। उत्तर के अंतिम वाक्य पर ध्यान दें: "मूल रूप से, अपवाद अक्सर तब तक नहीं होने चाहिए जब तक कि आपको महत्वपूर्ण शुद्धता के मुद्दे नहीं मिले हों, और यदि आपको महत्वपूर्ण शुद्धता के मुद्दे मिल गए हैं, तो प्रदर्शन आपके सामने सबसे बड़ी समस्या नहीं है।"
जॉन स्कीट

4
@PaLLockwood: मेरा कहना है कि अगर आपको प्रति सेकंड 200+ अपवाद मिले हैं, तो संभवत: यह पहले से ही इंगित करता है कि आप अपवादों का दुरुपयोग कर रहे हैं। यह मुझे आश्चर्यचकित नहीं करता है कि अक्सर ऐसा होता है, लेकिन इसका मतलब है कि प्रदर्शन का पहलू मेरी पहली चिंता नहीं होगी - अपवादों का दुरुपयोग होगा। एक बार मैंने अपवादों के सभी अनुचित उपयोगों को हटा दिया , तो मैं उनसे प्रदर्शन का एक महत्वपूर्ण हिस्सा होने की उम्मीद नहीं करूंगा।
जॉन स्कीट

4
@DavidJeske: आप उत्तर के बिंदु से चूक गए हैं। स्पष्ट रूप से एक अपवाद फेंकना सामान्य मूल्य वापस करने की तुलना में बहुत धीमा है। नहीं-किसी का तर्क है कि। सवाल यह है कि क्या वे बहुत धीमे हैं। यदि आप एक अपवाद को फेंकने के लिए उपयुक्त स्थिति में हैं और यह एक प्रदर्शन समस्या पैदा कर रहा है, तो आपको शायद बड़ी समस्याएं मिल गई हैं - क्योंकि यह बताता है कि आपके सिस्टम में एक बड़ी राशि गलत है। आम तौर पर, समस्या वास्तव में यह है कि आप अपवादों का उपयोग कर रहे हैं जब वे शुरू करने के लिए अनुपयुक्त हैं।
जॉन स्कीट

31

उस व्यक्ति से इसका निश्चित उत्तर है जिसने उन्हें लागू किया - क्रिस ब्रूमे। उन्होंने विषय के बारे में एक उत्कृष्ट ब्लॉग लेख लिखा (चेतावनी - इसकी बहुत लंबी) (चेतावनी 2 - इसकी बहुत अच्छी तरह से लिखी गई है, यदि आप एक तकनीकी विशेषज्ञ हैं तो आप इसे अंत तक पढ़ेंगे और फिर काम के बाद अपने घंटों को बनाना होगा :) )

कार्यकारी सारांश: वे धीमे हैं। उन्हें Win32 SEH अपवाद के रूप में कार्यान्वित किया जाता है, इसलिए कुछ भी रिंग 0 सीपीयू सीमा को पार कर जाएंगे! स्पष्ट रूप से वास्तविक दुनिया में, आप बहुत सारे अन्य काम कर रहे होंगे, इसलिए अजीब अपवाद बिल्कुल नहीं देखा जाएगा, लेकिन यदि आप उन्हें प्रोग्राम प्रवाह के लिए उपयोग करते हैं, तो उम्मीद है कि आपके ऐप को हथौड़ा मार दिया जाएगा। यह एमएस मार्केटिंग मशीन का एक और उदाहरण है जो हमें असंतुष्ट कर रहा है। मुझे याद है कि एक microsoftie ने हमें बताया था कि वे कैसे पूरी तरह से शून्य ओवरहेड करते हैं, जो कि पूर्ण tosh है।

क्रिस एक उचित उद्धरण देता है:

वास्तव में, सीएलआर आंतरिक रूप से इंजन के अप्रबंधित भागों में भी अपवादों का उपयोग करता है। हालांकि, अपवादों के साथ एक दीर्घकालिक दीर्घकालिक समस्या है और इसे आपके निर्णय में शामिल किया जाना चाहिए।


मैं इसका वास्तविक दुनिया के परीक्षणों में उल्लेख कर सकता हूं , जहां एक अशक्त प्रकार एक अपवाद के कारण कई बार "यह सामान्य कार्यक्रम प्रवाह है", जो महत्वपूर्ण प्रदर्शन समस्याओं के साथ समाप्त हो गया है। अल्वयस को याद है, अपवाद असाधारण मामलों के लिए हैं, किसी पर विश्वास न करें, जो अन्यथा कहता है या आप उस जैसे गीथूब धागे के साथ समाप्त करेंगे!
gbjbaanb 28

8

मुझे नहीं पता कि लोग क्या बात कर रहे हैं जब वे कहते हैं कि वे केवल धीमी गति से हैं अगर उन्हें फेंक दिया जाता है।

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

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

अपवाद भी ढेर पर वस्तुएं हैं - इसलिए यदि आप टन के अपवादों को फेंक रहे हैं, तो आप प्रदर्शन और स्मृति दोनों मुद्दों का कारण बन रहे हैं।

इसके अलावा, ACE टीम द्वारा लिखित "प्रदर्शन परीक्षण Microsoft .NET वेब अनुप्रयोग" की मेरी प्रति के अनुसार:

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

क्षेत्र में मेरे अपने अनुभव से पता चला कि अपवादों को कम करने से प्रदर्शन में काफी मदद मिली। निश्चित रूप से, प्रदर्शन परीक्षण के दौरान आपके द्वारा ध्यान में रखी जाने वाली अन्य चीजें हैं - उदाहरण के लिए, यदि आपका डिस्क I / O शूट किया गया है, या आपके प्रश्न सेकंड में हैं, तो आपका ध्यान केंद्रित होना चाहिए। लेकिन अपवादों को खोजना और हटाना उस रणनीति का एक महत्वपूर्ण हिस्सा होना चाहिए।


1
आपके द्वारा लिखे गए कुछ भी दावे के विपरीत नहीं है कि यदि वे फेंके गए हैं तो अपवाद केवल धीमे हैं। आप केवल स्थितियों में, जहां वे के बारे में बात की है कर रहे हैं फेंक दिया। जब आप अपवादों को हटाकर "महत्वपूर्ण रूप से प्रदर्शन में मदद करते हैं": 1) क्या वे सही त्रुटि की स्थिति थे, या सिर्फ उपयोगकर्ता की त्रुटि?
जॉन स्केट

2) क्या आप डिबगर के तहत चल रहे थे, या नहीं?
जॉन स्कीट

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

4
मुझे पता है - मैं MSFT में प्रीमियर टीम का हिस्सा था। :) चलो बस कहते हैं, बहुत - हजारों कुछ चरम मामलों में हमने देखा। लाइव डिबगर से जुड़ने जैसा कुछ भी नहीं है और सिर्फ अपवादों को देखना जितना तेजी से आप पढ़ सकते हैं। पूर्व की गति धीमी है - इसलिए एक DB से जुड़ रहा है, इसलिए आप इसे तब करते हैं जब यह समझ में आता है।
Cory Foy

5
Cory, मुझे लगता है कि "केवल धीमी गति से जब वे फेंके जाते हैं" की बात यह है कि आपको केवल पकड़ने / अंत में ब्लॉक की उपस्थिति के कारण प्रदर्शन के बारे में चिंता करने की ज़रूरत नहीं है। यानी ये अपने आप में एक प्रदर्शन हिट का कारण नहीं बनता है, केवल एक वास्तविक अपवाद उदाहरण की घटना है।
इयान हॉरविल

6

जैसा कि मैं समझता हूं कि यह तर्क नहीं है कि अपवादों को फेंकना बुरा है, वे प्रति धीमे हैं। इसके बजाय, यह अधिक पारंपरिक सशर्त निर्माणों के बजाय सामान्य अनुप्रयोग तर्क को नियंत्रित करने के प्रथम श्रेणी के तरीके के रूप में थ्रो / कैच निर्माण का उपयोग करने के बारे में है।

अक्सर सामान्य अनुप्रयोग तर्क में आप लूपिंग करते हैं जहां एक ही क्रिया हजारों / लाखों बार दोहराई जाती है। इस मामले में, कुछ बहुत ही सरल रूपरेखा (स्टॉपवॉच वर्ग देखें) के साथ, आप खुद के लिए देख सकते हैं कि एक अपवाद कहने के बजाय एक अपवाद कहें तो कथन काफी धीमा हो सकता है।

वास्तव में मैंने एक बार पढ़ा था कि Microsoft पर .NET टीम ने विशेष रूप से आधार FCL प्रकारों में से कई में .NET 2.0 में TryXXXXX विधियों को पेश किया क्योंकि ग्राहक शिकायत कर रहे थे कि उनके अनुप्रयोगों का प्रदर्शन इतना धीमा था।

यह कई मामलों में पता चलता है क्योंकि ग्राहक लूप में मूल्यों के प्रकार रूपांतरण का प्रयास कर रहे थे, और प्रत्येक प्रयास विफल हो गया। एक रूपांतरण अपवाद को फेंक दिया गया और फिर एक अपवाद हैंडलर द्वारा पकड़ा गया जिसने फिर अपवाद को निगल लिया और लूप जारी रखा।

Microsoft अब सलाह देता है कि इस तरह के संभावित प्रदर्शन के मुद्दों से बचने के लिए विशेष रूप से इस स्थिति में TryXXX विधियों का उपयोग किया जाना चाहिए।

मैं गलत हो सकता हूं, लेकिन ऐसा लगता है कि आप "बेंचमार्क" की सत्यता के बारे में निश्चित नहीं हैं, जिसके बारे में आपने पढ़ा है। सरल उपाय: इसे अपने लिए आजमाएं।


मुझे लगा कि इंटर्नलली वे "कोशिश" फ़ंक्शन अपवादों का भी उपयोग करते हैं?
ग्रेग

1
ये "कोशिश" फ़ंक्शन इनपुट मान को पार्स करने में विफलता के लिए आंतरिक रूप से अपवाद नहीं फेंकते हैं। हालांकि वे अभी भी अन्य त्रुटि स्थितियों के लिए अपवाद फेंकते हैं, जैसे कि ArgumentException।
ऐश

मुझे लगता है कि यह जवाब किसी अन्य की तुलना में मुद्दे के दिल के करीब हो जाता है। यह कहना कि 'उचित परिस्थितियों में केवल अपवादों का उपयोग करना' वास्तव में सवाल का जवाब नहीं देता है - वास्तविक अंतर्दृष्टि यह है कि नियंत्रण प्रवाह के लिए सी # अपवादों का उपयोग करना सामान्य सशर्त निर्माणों की तुलना में बहुत धीमा है। आपको अन्यथा सोचने के लिए क्षमा किया जा सकता है। OCaml में, अपवाद कमोबेश GOTO हैं और अनिवार्य सुविधाओं का उपयोग करते समय ब्रेक को लागू करने का स्वीकृत तरीका । मेरे विशेष मामले में, एक तंग लूप int.Parse () प्लस try / catch बनाम int.TryParse () की जगह एक महत्वपूर्ण प्रदर्शन को बढ़ावा दिया।
ह्यूज डब्ल्यू

4

मेरे एक्सएमपीपी सर्वर ने एक बड़ी गति को बढ़ावा दिया (क्षमा करें, कोई वास्तविक संख्या नहीं, विशुद्ध रूप से अवलोकन के बाद) मैंने लगातार उन्हें होने से रोकने की कोशिश की (जैसे कि अगर एक सॉकेट से जुड़ा हुआ है और अधिक डेटा पढ़ने की कोशिश करने से पहले जाँच कर रहा है) और खुद को उनसे बचने के तरीके दे रहा है (उल्लिखित TryX तरीकों)। यह केवल लगभग 50 सक्रिय (चैटिंग) आभासी उपयोगकर्ताओं के साथ था।


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

3

इस चर्चा में अपने हाल के अनुभव को जोड़ने के लिए: ऊपर लिखे गए अधिकांश शब्दों के अनुरूप, मैंने पाया कि अपवादों को बहुत धीमी गति से फेंक दिया जाता है जब बार-बार चलने वाले डिबगर के बिना भी। मैंने कोड के बारे में पाँच पंक्तियों को बदलकर 60% से लिख रहे एक बड़े कार्यक्रम के प्रदर्शन को बढ़ा दिया: अपवादों को फेंकने के बजाय एक रिटर्न-कोड मॉडल पर स्विच करना। दी गई, प्रश्न में कोड हजारों बार चल रहा था और संभवतः मैंने इसे बदलने से पहले हजारों अपवादों को फेंक दिया। इसलिए मैं ऊपर दिए गए कथन से सहमत हूं: जब कुछ महत्वपूर्ण वास्तव में गलत हो जाता है, तो अपवादों को फेंक दें, किसी भी "अपेक्षित" स्थितियों में आवेदन प्रवाह को नियंत्रित करने के तरीके के रूप में नहीं।


2

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

वे निश्चित रूप से त्रुटि कोड का उपयोग करने के लायक हैं, लाभ विशाल IMO हैं।


2

मुझे अपवादों के साथ कभी कोई प्रदर्शन समस्या नहीं हुई। मैं अपवादों का बहुत उपयोग करता हूं - अगर मैं कर सकता हूं तो मैं कभी भी रिटर्न कोड का उपयोग नहीं करता। वे एक बुरा अभ्यास हैं, और मेरी राय में, स्पेगेटी कोड की तरह गंध है।

मुझे लगता है कि यह सब आप के अपवादों का उपयोग करने के लिए उबालता है: यदि आप उन्हें रिटर्न कोड (स्टैक कैच और रीथ्रोस में प्रत्येक विधि कॉल) की तरह उपयोग करते हैं, तो, हाँ, वे धीमे होंगे, क्योंकि आपके पास प्रत्येक एकल कैच / थ्रो ओवरहेड है।

लेकिन अगर आप स्टैक के निचले भाग पर फेंकते हैं और शीर्ष पर पकड़ते हैं (आप एक फेंक / कैच के साथ रिटर्न कोड की पूरी श्रृंखला को प्रतिस्थापित करते हैं), तो सभी महंगा ऑपरेशन एक बार किए जाते हैं।

दिन के अंत में, वे एक मान्य भाषा विशेषता हैं।

बस अपनी बात साबित करने के लिए

कृपया इस लिंक पर कोड चलाएं (उत्तर के लिए बहुत बड़ा)।

मेरे कंप्यूटर पर परिणाम:

marco@sklivvz:~/develop/test$ mono Exceptions.exe | grep PM
10/2/2008 2:53:32 PM
10/2/2008 2:53:42 PM
10/2/2008 2:53:52 PM

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


2

लेकिन मोनो .net स्टैंडअलोन मोड की तुलना में 10x तेजी से अपवाद फेंकता है, और .net स्टैंडअलोन मोड .net डीबगर मोड की तुलना में तेजी से अपवाद एक्सएक्सएक्स को फेंकता है। (परीक्षण मशीनों में एक ही सीपीयू मॉडल है)

int c = 1000000;
int s = Environment.TickCount;
for (int i = 0; i < c; i++)
{
    try { throw new Exception(); }
    catch { }
}
int d = Environment.TickCount - s;

Console.WriteLine(d + "ms / " + c + " exceptions");

1

रिलीज मोड में ओवरहेड न्यूनतम है।

जब तक आप एक पुनरावर्ती फैशन में प्रवाह-नियंत्रण (उदाहरण, गैर-स्थानीय निकास) के लिए अपवादों का उपयोग करने जा रहे हैं, मुझे संदेह है कि आप अंतर को नोटिस करने में सक्षम होंगे।


1

विंडोज सीएलआर पर, गहराई -8 कॉल श्रृंखला के लिए, एक अपवाद फेंकना रिटर्न वैल्यू की जांच करने और प्रचार करने की तुलना में 750 गुना धीमा है। (बेंचमार्क के लिए नीचे देखें)

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

मोनो रनटाइम में अपवाद (किसी भी प्लेटफ़ॉर्म पर) बहुत तेज़ होते हैं, क्योंकि यह SEH के साथ एकीकृत नहीं होता है। हालाँकि, कई रनटाइम के अपवादों को पार करते समय कार्यक्षमता की हानि होती है क्योंकि यह SEH जैसी किसी चीज़ का उपयोग नहीं करता है।

विंडोज सीएलआर के लिए अपवाद बनाम रिटर्न मान के मेरे बेंचमार्क से परिणाम संक्षिप्त हैं।

baseline: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 13.0007 ms
baseline: recurse_depth 8, error_freqeuncy 0.25 (0), time elapsed 13.0007 ms
baseline: recurse_depth 8, error_freqeuncy 0.5 (0), time elapsed 13.0008 ms
baseline: recurse_depth 8, error_freqeuncy 0.75 (0), time elapsed 13.0008 ms
baseline: recurse_depth 8, error_freqeuncy 1 (0), time elapsed 14.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0 (0), time elapsed 13.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0.25 (249999), time elapsed 14.0008 ms
retval_error: recurse_depth 5, error_freqeuncy 0.5 (499999), time elapsed 16.0009 ms
retval_error: recurse_depth 5, error_freqeuncy 0.75 (999999), time elapsed 16.001 ms
retval_error: recurse_depth 5, error_freqeuncy 1 (999999), time elapsed 16.0009 ms
retval_error: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 20.0011 ms
retval_error: recurse_depth 8, error_freqeuncy 0.25 (249999), time elapsed 21.0012 ms
retval_error: recurse_depth 8, error_freqeuncy 0.5 (499999), time elapsed 24.0014 ms
retval_error: recurse_depth 8, error_freqeuncy 0.75 (999999), time elapsed 24.0014 ms
retval_error: recurse_depth 8, error_freqeuncy 1 (999999), time elapsed 24.0013 ms
exception_error: recurse_depth 8, error_freqeuncy 0 (0), time elapsed 31.0017 ms
exception_error: recurse_depth 8, error_freqeuncy 0.25 (249999), time elapsed 5607.3208     ms
exception_error: recurse_depth 8, error_freqeuncy 0.5 (499999), time elapsed 11172.639  ms
exception_error: recurse_depth 8, error_freqeuncy 0.75 (999999), time elapsed 22297.2753 ms
exception_error: recurse_depth 8, error_freqeuncy 1 (999999), time elapsed 22102.2641 ms

और यहाँ कोड है ..

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {

public class TestIt {
    int value;

    public class TestException : Exception { } 

    public int getValue() {
        return value;
    }

    public void reset() {
        value = 0;
    }

    public bool baseline_null(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            return shouldfail;
        } else {
            return baseline_null(shouldfail,recurse_depth-1);
        }
    }

    public bool retval_error(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            if (shouldfail) {
                return false;
            } else {
                return true;
            }
        } else {
            bool nested_error = retval_error(shouldfail,recurse_depth-1);
            if (nested_error) {
                return true;
            } else {
                return false;
            }
        }
    }

    public void exception_error(bool shouldfail, int recurse_depth) {
        if (recurse_depth <= 0) {
            if (shouldfail) {
                throw new TestException();
            }
        } else {
            exception_error(shouldfail,recurse_depth-1);
        }

    }

    public static void Main(String[] args) {
        int i;
        long l;
        TestIt t = new TestIt();
        int failures;

        int ITERATION_COUNT = 1000000;


        // (0) baseline null workload
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    t.baseline_null(shoulderror,recurse_depth);
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "baseline: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));
            }
        }


        // (1) retval_error
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    if (!t.retval_error(shoulderror,recurse_depth)) {
                        failures++;
                    }
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "retval_error: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));
            }
        }

        // (2) exception_error
        for (int recurse_depth = 2; recurse_depth <= 10; recurse_depth+=3) {
            for (float exception_freq = 0.0f; exception_freq <= 1.0f; exception_freq += 0.25f) {            
                int EXCEPTION_MOD = (exception_freq == 0.0f) ? ITERATION_COUNT+1 : (int)(1.0f / exception_freq);            

                failures = 0;
                DateTime start_time = DateTime.Now;
                t.reset();              
                for (i = 1; i < ITERATION_COUNT; i++) {
                    bool shoulderror = (i % EXCEPTION_MOD) == 0;
                    try {
                        t.exception_error(shoulderror,recurse_depth);
                    } catch (TestException e) {
                        failures++;
                    }
                }
                double elapsed_time = (DateTime.Now - start_time).TotalMilliseconds;
                Console.WriteLine(
                    String.Format(
                      "exception_error: recurse_depth {0}, error_freqeuncy {1} ({2}), time elapsed {3} ms",
                        recurse_depth, exception_freq, failures,elapsed_time));         }
        }
    }
}


}

5
प्रश्न के बिंदु को गायब करने के अलावा, कृपया दिनांक-समय का उपयोग न करें। कैसे बेंचमार्क के लिए - स्टॉपवॉच का उपयोग करें, जो बीते हुए समय को मापने के लिए डिज़ाइन किया गया है। यह यहाँ एक मुद्दा नहीं होना चाहिए क्योंकि आप काफी लंबे समय से माप कर रहे हैं, लेकिन यह आदत में आने लायक है।
जॉन स्कीट

इसके विपरीत, सवाल "अपवाद धीमा हैं", अवधि। यह विशेष रूप से इस विषय से बचने के लिए कहा जाता है कि अपवादों को कब फेंकना है, क्योंकि यह विषय तथ्यों को अस्पष्ट करता है। अपवादों का प्रदर्शन क्या है?
डेविड जेसके

0

अपवादों को पकड़ने के साथ जुड़े प्रदर्शन पर एक त्वरित ध्यान दें।

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


1
हालांकि, अपवादों की उपस्थिति अनुकूलन को प्रभावित कर सकती है - स्पष्ट अपवाद हैंडलर के साथ तरीके कठिन इनलाइन हैं, और निर्देश पुन: व्यवस्थित करना उनके द्वारा सीमित है।
ईमोन नेरबोन 14

-1

जब उपयोग करने के लिए दूसरों के लिए कक्षाएं / फ़ंक्शन लिखते हैं, तो यह कहना मुश्किल होता है कि अपवाद कब उपयुक्त हैं। बीसीएल के कुछ उपयोगी हिस्से हैं जिन्हें मुझे खोदना और पिनवोक के लिए जाना था क्योंकि वे त्रुटियों को वापस करने के बजाय अपवादों को फेंक देते हैं। कुछ मामलों के लिए आप इसके आस-पास काम कर सकते हैं लेकिन दूसरों के लिए जैसे कि System.Management और Performance Counters वहाँ usages हैं जहाँ आपको लूप्स करने की आवश्यकता होती है जिसमें अपवाद BCL द्वारा अक्सर फेंके जाते हैं।

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

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


2
यह पोस्टर के " मैं कब और अपवादों को नहीं फेंकना है " कथन के बारे में चर्चा नहीं चाहता है, फिट नहीं लगता है ।
२३:१४
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.