C ++ में अपवाद वास्तव में धीमे हैं


98

मैं C ++ में सिस्टेमैटिक एरर हैंडलिंग देख रहा था - आंद्रेई अलेक्जेंड्रेस्कु उनका दावा है कि C ++ में एक्सेप्शन बहुत धीमे हैं।

क्या यह अभी भी C ++ 98 के लिए सही है?


42
यह पूछने का कोई मतलब नहीं है कि क्या "सी ++ 98 अपवाद" "सी ++ 03 अपवाद" या "सी ++ 11 अपवाद" की तुलना में तेज / धीमी हैं। उनका प्रदर्शन इस बात पर निर्भर है कि कंपाइलर उन्हें आपके कार्यक्रमों में कैसे लागू करता है, और C ++ मानक कुछ भी नहीं कहता है कि उन्हें कैसे लागू किया जाना चाहिए; केवल आवश्यकता यह है कि उनके व्यवहार को मानक ("जैसा-यदि" नियम) का पालन करना चाहिए।
सिलिको में

संबंधित (लेकिन वास्तव में डुप्लिकेट नहीं) सवाल: stackoverflow.com/questions/691168/…
फिलिप

2
हां, यह बहुत धीमा है, लेकिन उन्हें एक सामान्य ऑपरेशन के लिए नहीं फेंकना चाहिए या एक शाखा के रूप में इस्तेमाल किया जाना चाहिए
BЈови12

मुझे एक ऐसा ही सवाल मिला है ।
पेपरबर्डमास्टर

यह स्पष्ट करने के लिए कि Bћовић ने क्या कहा है, अपवादों का उपयोग करने से डरना नहीं है। यह तब होता है जब एक अपवाद फेंक दिया जाता है कि आप समय लेने वाली कार्रवाई का सामना करते हैं (संभावित रूप से)। मैं इस बात से भी उत्सुक हूं कि आप विशेष रूप से C ++ 89 के लिए क्यों जानना चाहते हैं ... कि नवीनतम संस्करण C ++ 11 है, और इसे चलाने के लिए अपवादों को लागू करने में लगने वाले समय को परिभाषित किया गया है, इसलिए मेरा 'संभावित' समय लेने वाला ।
thecoshman 8

जवाबों:


162

अपवादों के लिए आज इस्तेमाल किया जाने वाला मुख्य मॉडल (इटेनियम एबीआई, वीसी ++ 64 बिट्स) जीरो-कॉस्ट मॉडल अपवाद है।

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

ठेठ if (error)रणनीति की तुलना में :

  • शून्य-लागत मॉडल, जैसा कि नाम से पता चलता है, कोई अपवाद नहीं होने पर स्वतंत्र है
  • ifएक अपवाद होने पर इसकी लागत लगभग 10x / 20x होती है

हालांकि, लागत को मापने के लिए तुच्छ नहीं है:

  • साइड-टेबल आमतौर पर ठंडा होता है , और इस तरह इसे मेमोरी से लाने में लंबा समय लगता है
  • सही हैंडलर के निर्धारण में RTTI शामिल है: कई RTTI डिस्क्रिप्टर लाने के लिए, मेमोरी के चारों ओर बिखरे हुए, और चलाने के लिए जटिल ऑपरेशन (मूल रूप से dynamic_castप्रत्येक हैंडलर के लिए एक परीक्षण)

तो, ज्यादातर कैश की कमी होती है, और इस तरह शुद्ध सीपीयू कोड की तुलना में तुच्छ नहीं।

नोट: अधिक जानकारी के लिए, TR18015 रिपोर्ट पढ़ें , अध्याय 5.4 अपवाद हैंडलिंग (पीडीएफ)

तो, हाँ, अपवाद असाधारण पथ पर धीमा हैं , लेकिन वे ifसामान्य रूप से स्पष्ट जांच ( रणनीति) की तुलना में अधिक तेज हैं ।

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


फर्क पड़ता है क्या ?

मैं यह दावा करता हूं कि ऐसा नहीं है। एक कार्यक्रम को ध्यान में पठनीयता के साथ लिखा जाना चाहिए , प्रदर्शन नहीं (कम से कम, पहली कसौटी के रूप में नहीं)। अपवादों का उपयोग तब किया जाता है जब कोई यह उम्मीद करता है कि कॉलर मौके पर विफलता को संभालने की इच्छा नहीं कर सकता है या नहीं, और इसे स्टैक को पारित कर देगा। बोनस: C ++ 11 अपवादों में मानक पुस्तकालय का उपयोग करते हुए थ्रेड्स के बीच marshalled किया जा सकता है।

यह सूक्ष्म हालांकि है, मुझे लगता है कि दावा map::findफेंक नहीं करना चाहिए, लेकिन मैं के साथ ठीक हूँ map::findलौटने एक checked_ptrजो अगर एक प्रयास भिन्नता के लिए यह विफल रहता है, क्योंकि यह के अशक्त फेंकता है: उत्तरार्द्ध मामले में, वर्ग के मामले कि Alexandrescu शुरू की, के रूप में फोन करने वाले चुनता स्पष्ट जाँच और अपवादों पर निर्भर होने के बीच। उसे अधिक जिम्मेदारी दिए बिना कॉल करने वाले को सशक्त बनाना आमतौर पर अच्छे डिजाइन का संकेत है।


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

2
@ चेरसन्ध।-अल्फ: (0), (1) और (3) किया गया: धन्यवाद। शुद्धता के बारे में (2), जबकि यह पठनीयता को रौंदता है, मैं अन्य त्रुटियों से निपटने वाली रणनीतियों की तुलना में अधिक सही कोड के लिए जाने वाले अपवादों के बारे में अनिश्चित हूं (यह निष्पादन अपवादों के कई अदृश्य रास्तों के बारे में भूलना आसान है)।
Matthieu M.

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

4
> जीरो-कॉस्ट मॉडल, जैसा कि नाम से ही स्पष्ट है, जब कोई अपवाद नहीं होता है तो यह वास्तव में विस्तार के बेहतरीन स्तरों तक सच नहीं होता है। अधिक कोड उत्पन्न करने पर हमेशा एक प्रदर्शन प्रभाव पड़ता है, भले ही छोटा और सूक्ष्म ... OS को निष्पादन योग्य लोड करने में थोड़ा अधिक समय लग सकता है, या आपको अधिक i-cache मिसेज़ मिलेंगे। इसके अलावा, स्टैक अनइंडिंग कोड के बारे में क्या? इसके अलावा, उन प्रयोगों के बारे में जो आप तर्कसंगत सोच के साथ समझने की कोशिश करने के बजाय प्रभावों को मापने के लिए क्या कर सकते हैं?
जेरिको

2
@ जेरिको: मेरा मानना ​​है कि मैंने आपके अधिकांश प्रश्नों को पहले ही, वास्तव में संबोधित किया था। लोड करने का समय प्रभावित नहीं होना चाहिए (ठंडा कोड लोड नहीं किया जाना चाहिए), आई-कैश को प्रभावित नहीं किया जाना चाहिए (शीत कोड को आई-कैश में नहीं बनाना चाहिए), ... इसलिए एक लापता प्रश्न को संबोधित करने के लिए: "कैसे मापने के लिए" => किसी भी अपवाद को कॉल के साथ फेंकने की जगह abortआपको द्विआधारी आकार के पदचिह्न को मापने और यह जांचने की अनुमति देगा कि लोड-टाइम / आई-कैश समान व्यवहार करता है। बेशक, बेहतर नहीं किसी भी हिट abort...
Matthieu M.

60

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


क्या अन्य भाषाओं की तुलना में अपवाद विशेष रूप से C ++ में धीमी हैं?

दावा फिर से करें

"मैं C ++ में सिस्टेमैटिक एरर हैंडलिंग देख रहा था - आंद्रेई अलेक्जेंड्रेस्कु का दावा है कि C ++ में एक्सेप्शन बहुत धीमा है।"

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

सामान्य तौर पर, ज्यादातर भाषा की परवाह किए बिना, दो बुनियादी भाषा सुविधाएँ जो कि बाकी की तुलना में परिमाण धीमी करने के आदेश हैं, क्योंकि वे रूटीन के कॉल का अनुवाद करते हैं जो जटिल डेटा संरचनाओं को संभालते हैं,

  • अपवाद फेंकने, और

  • गतिशील स्मृति आवंटन।

सी ++ में खुशी से एक बार-महत्वपूर्ण कोड में दोनों से बच सकते हैं।

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

ग्रेटर जटिलता का अर्थ है, रखरखाव पर अधिक समय और कोड के पुन: उपयोग से कोई लाभ नहीं, जो वास्तविक मौद्रिक लागत हैं, भले ही अनुमान लगाना या मापना मुश्किल हो। यानी, C ++ एक के साथ, यदि वांछित हो, तो निष्पादन दक्षता के लिए कुछ प्रोग्रामर दक्षता का व्यापार करें। क्या ऐसा करना काफी हद तक एक इंजीनियरिंग और आंत-संबंधी निर्णय है, क्योंकि व्यवहार में केवल लाभ, लागत नहीं, आसानी से अनुमान लगाया जा सकता है और मापा जा सकता है।


C ++ अपवाद फेंक प्रदर्शन के कोई उद्देश्य उपाय हैं?

हां, अंतर्राष्ट्रीय C ++ मानकीकरण समिति ने C ++ प्रदर्शन, TR18015 पर एक तकनीकी रिपोर्ट प्रकाशित की है ।


इसका क्या मतलब है कि अपवाद "धीमी" हैं?

मुख्य रूप से इसका मतलब है कि हैंडलर की खोज के कारण, throwउदाहरण intके लिए, असाइनमेंट की तुलना में बहुत लंबा समय ले सकता है ।

TR18015 के रूप में इसके खंड 5.4 "अपवाद" में चर्चा की गई है कि कार्यान्वयन रणनीतियों को संभालने वाले दो प्रमुख अपवाद हैं,

  • एप्रोच जहां प्रत्येक- tryडिस्क डायनामिक रूप से अपवाद पकड़ने को सेट करता है, ताकि हैंडलर की डायनामिक चेन की खोज एक अपवाद को फेंकने पर की जाए और

  • एप्रोच जहां संकलक स्थिर लुक-अप टेबल उत्पन्न करता है जो कि हैंडलर को फेंकने के लिए निर्धारित करने के लिए उपयोग किया जाता है।

32-बिट विंडोज में पहला बहुत लचीला और सामान्य दृष्टिकोण लगभग मजबूर है, जबकि 64-बिट भूमि और * निक्स-लैंड में दूसरा अधिक कुशल दृष्टिकोण आमतौर पर उपयोग किया जाता है।

जैसा कि उस रिपोर्ट में चर्चा की गई है, प्रत्येक दृष्टिकोण के लिए तीन मुख्य क्षेत्र हैं जहां दक्षता पर प्रभाव से निपटने के अपवाद हैं:

  • try-blocks,

  • नियमित कार्य (अनुकूलन अवसर), और

  • throw-expressions।

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

दुर्भाग्य से, रिपोर्ट, 2006 से, पहले से ही 2012 के उत्तरार्ध के रूप में पहले से ही थोड़ा सा दिनांकित है, और जहां तक ​​मुझे पता है कि कुछ भी तुलनीय नहीं है जो नया है।

एक अन्य महत्वपूर्ण परिप्रेक्ष्य यह है कि प्रदर्शन पर अपवादों के उपयोग का प्रभाव सहायक भाषा सुविधाओं की अलग-थलग दक्षता से बहुत अलग है, क्योंकि रिपोर्ट नोट्स के अनुसार,

"अपवाद से निपटने पर विचार करते समय, इसे त्रुटियों से निपटने के वैकल्पिक तरीकों के विपरीत होना चाहिए।"

उदाहरण के लिए:

  • विभिन्न प्रोग्रामिंग शैलियों (शुद्धता) के कारण रखरखाव की लागत

  • निरर्थक कॉल साइट ifविफलता जाँच बनाम केंद्रीकृतtry

  • कैशिंग समस्याएं (उदाहरण के लिए छोटा कोड कैश में फिट हो सकता है)

रिपोर्ट में विचार करने के लिए पहलुओं की एक अलग सूची है, लेकिन वैसे भी निष्पादन दक्षता के बारे में कठिन तथ्यों को प्राप्त करने का एकमात्र व्यावहारिक तरीका संभवतः एक ही कार्यक्रम को अपवाद का उपयोग करके लागू करना है और अपवादों का उपयोग नहीं करना है, विकास के समय पर एक तय टोपी के भीतर, और डेवलपर्स के साथ। हर तरह से परिचित है, और फिर MEASURE


अपवादों के उपरि से बचने का एक अच्छा तरीका क्या है?

सुधार लगभग हमेशा दक्षता ट्रम्प करता है।

अपवादों के बिना, निम्नलिखित आसानी से हो सकता है:

  1. कुछ कोड P एक संसाधन प्राप्त करने या कुछ जानकारी की गणना करने के लिए है।

  2. कॉलिंग कोड C को सफलता / विफलता के लिए जाँचना चाहिए था, लेकिन नहीं।

  3. एक गैर-मौजूद संसाधन या अमान्य जानकारी का उपयोग C के बाद के कोड में किया जाता है, जिससे सामान्य तबाही होती है।

मुख्य समस्या बिंदु (2) है, जहां सामान्य रिटर्न कोड योजना के साथ कॉलिंग सी चेक करने के लिए मजबूर नहीं किया जाता है।

दो मुख्य दृष्टिकोण हैं जो इस तरह की जाँच को बल देते हैं:

  • जहां P फेल होने पर सीधे एक अपवाद को फेंक देता है।

  • जहां P एक वस्तु देता है जिसे C को अपने मुख्य मूल्य (अन्यथा एक अपवाद या समाप्ति) का उपयोग करने से पहले निरीक्षण करना पड़ता है ।

दूसरा दृष्टिकोण था, AFAIK, जिसे सबसे पहले बार्टन और नेकमैन ने अपनी पुस्तक * साइंटिफिक एंड इंजीनियरिंग C ++: एन इंट्रोडक्शन विद एडवांस्ड टेक्नीक्स एंड एग्ज़ाम्पल, में वर्णित किया है , जहाँ उन्होंने Fallow"संभावित" फंक्शन रिजल्ट के लिए क्लास बुलाया । एक समान वर्ग जिसे optionalअब बूस्ट लाइब्रेरी द्वारा पेश किया जाता है। और आप आसानी से एक Optionalवर्ग को लागू कर सकते हैं , std::vectorगैर-पीओडी परिणाम के मामले के लिए एक मूल्य वाहक के रूप में।

पहले दृष्टिकोण के साथ कॉलिंग सी के पास अपवाद संचालन तकनीकों का उपयोग करने के अलावा कोई विकल्प नहीं है। दूसरे दृष्टिकोण के साथ, हालांकि, कॉलिंग कोड सी ही यह तय कर सकता है कि ifआधारित जाँच करना है, या सामान्य अपवाद हैंडलिंग। इस प्रकार, दूसरा दृष्टिकोण प्रोग्रामर बनाम निष्पादन समय दक्षता व्यापार बंद करने का समर्थन करता है।


अपवाद प्रदर्शन पर विभिन्न C ++ मानकों का क्या प्रभाव है?

"मैं जानना चाहता हूं कि क्या यह अभी भी C ++ 98 के लिए सही है"

C ++ 98 पहला C ++ मानक था। अपवादों के लिए इसने अपवाद वर्गों के एक मानक पदानुक्रम (दुर्भाग्य से अपूर्ण) को पेश किया। प्रदर्शन पर मुख्य प्रभाव अपवाद विनिर्देशों की संभावना थी (सी ++ 11 में हटा दिया गया), जो हालांकि मुख्य विंडोज सी ++ कंपाइलर विज़ुअल सी ++ द्वारा पूरी तरह से कभी लागू नहीं किया गया था: विजुअल सी ++ सी ++ 98 अपवाद विनिर्देश वाक्यविन्यास को स्वीकार करता है, लेकिन सिर्फ उपेक्षा करता है अपवाद विनिर्देशों।

C ++ 03, C ++ 98 का ​​सिर्फ एक तकनीकी गलियारा था। C ++ 03 में केवल वास्तव में नया था मूल्य आरंभीकरण । जिसका अपवादों से कोई लेना-देना नहीं है।

C ++ 11 मानक सामान्य अपवाद विनिर्देशों को हटा दिया गया, और noexceptकीवर्ड के साथ बदल दिया गया ।

C ++ 11 मानक ने भी अपवादों के भंडारण और पुनर्संरक्षण के लिए समर्थन जोड़ा, जो C भाषा के कॉलबैक में C ++ अपवादों के प्रचार के लिए महान है। यह समर्थन प्रभावी रूप से यह बताता है कि वर्तमान अपवाद को कैसे संग्रहीत किया जा सकता है। हालाँकि, जहाँ तक मुझे पता है कि प्रदर्शन पर कोई असर नहीं पड़ता है, सिवाय इस बात के कि नए कोड में अपवाद आसानी से C भाषा के कॉलबैक के दोनों ओर आसानी से उपयोग किए जा सकते हैं।


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

4
"एक अपवाद को फेंकने में आवंटन और स्टैक अनइंडिंग दोनों शामिल हैं"। यह भी स्पष्ट रूप से सामान्य रूप से सच नहीं है और, फिर से, OCaml एक काउंटर उदाहरण है। कचरा एकत्र की गई भाषाओं में स्टैक को खोलना नहीं है क्योंकि वहाँ कोई विनाशकारी नहीं हैं, इसलिए आप केवल longjmpहैंडलर के पास हैं।
JD

2
@JonHarrop: संभवत: आप इस बात से अनजान होंगे कि अपवाद हैंडलिंग के लिए पायन के पास आखिरकार क्लॉज है। इसका मतलब है कि पायथन कार्यान्वयन या तो स्टैक अनइंडिंग है या पायथन नहीं है। आप उन विषयों से पूरी तरह अनभिज्ञ प्रतीत होते हैं जिनके बारे में आप (काल्पनिक) दावे करते हैं। माफ़ करना।
चीयर्स एंड हीथ। - अल्फ

2
@ चेरसन्ध।-अल्फ: "पायथन में अपवाद से निपटने के लिए एक अंत-खंड है। इसका मतलब है कि पायथन कार्यान्वयन में या तो स्टैक अनइंडिंग है या पायथन नहीं है"। try..finallyनिर्माण स्टैक के बिना लागू किया जा सकता। F #, C # और जावा सभी try..finallyस्टैक अनइंडिंग का उपयोग किए बिना लागू करते हैं। आप बस longjmpहैंडलर को (जैसा कि मैंने पहले ही समझाया)।
JD

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

12

यह कंपाइलर पर निर्भर करता है।

उदाहरण के लिए, जीसीसी अपवादों को संभालते हुए बहुत खराब प्रदर्शन के लिए जाना जाता था, लेकिन पिछले कुछ वर्षों में यह काफी बेहतर हुआ।

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

अपवाद कोड को उस तरीके से बाहर निकालने के लिए कोड को अधिक पठनीय बनाने का एक शानदार तरीका है, लेकिन जैसे ही वे सामान्य कार्यक्रम प्रवाह का हिस्सा बनते हैं, वे वास्तव में अनुसरण करना कठिन हो जाते हैं। याद रखें कि भेस में throwएक बहुत सुंदर है goto catch


-1 सवाल को फिर से खड़ा करें क्योंकि यह "C ++ 98 के लिए अभी भी सही है", यह निश्चित रूप से संकलक पर निर्भर नहीं करता है। इसके अलावा, यह उत्तर throw new Exceptionएक जावा-इस्म है। एक नियम के रूप में एक संकेत कभी नहीं फेंकना चाहिए ।
चीयर्स एंड हीथ। - अल्फ

1
क्या 98 मानक वास्तव में यह बताता है कि अपवादों को कैसे लागू किया जाता है?
Thecoshman

6
सी ++ 98 एक आईएसओ मानक है, संकलक नहीं। कई कंपाइलर हैं जो इसे लागू करते हैं।
फिलिप

3
@Thecoshman: नहीं। C ++ मानक कुछ भी नहीं कहता है कि कैसे कुछ भी लागू किया जाना चाहिए (मानक के "कार्यान्वयन सीमाएं" के संभावित अपवाद के साथ)।
सिलिको में

2
@ इनीसिलिको तो मैं केवल तार्किक निष्कर्ष निकाल सकता हूं कि (झटके से) यह कार्यान्वयन को परिभाषित किया गया है (पढ़ें, संकलक विशिष्ट) कैसे असाधारण प्रदर्शन करता है।
Thecoshman

12

जब तक आप कोड को असेंबली या बेंचमार्क में परिवर्तित नहीं करते, आप प्रदर्शन के बारे में कभी दावा नहीं कर सकते।

यहाँ आप क्या देख रहे हैं: (त्वरित बेंच)

त्रुटि कोड घटना के प्रतिशत के प्रति संवेदनशील नहीं है। अपवादों में थोड़ा बहुत उपरि होता है जब तक कि वे कभी भी फेंक नहीं दिए जाते हैं। एक बार जब आप उन्हें फेंक देते हैं, तो दुख शुरू हो जाता है। इस उदाहरण में, इसे 0%, 1%, 10%, 50% और 90% मामलों में फेंक दिया जाता है। जब अपवादों को 90% समय के लिए फेंक दिया जाता है, तो कोड उस मामले की तुलना में 8 गुना धीमा होता है जहां अपवादों को समय का 10% फेंक दिया जाता है। जैसा कि आप देखते हैं, अपवाद वास्तव में धीमा हैं। अगर उन्हें बार-बार फेंका जाए तो उनका इस्तेमाल न करें। यदि आपके आवेदन की कोई वास्तविक समय की आवश्यकता नहीं है, तो उन्हें फेंकने के लिए स्वतंत्र महसूस करें यदि वे बहुत कम होते हैं।

आप उनके बारे में कई विरोधाभासी राय देखते हैं। लेकिन आखिरकार, क्या अपवाद धीमे हैं? मैं न्याय नहीं करता। बस बेंचमार्क देखो।

C ++ अपवाद प्रदर्शन मानदंड


4

हां, लेकिन इससे कोई फर्क नहीं पड़ता। क्यों?
इसे पढ़ें:
https://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exc.nx

मूल रूप से यह कहता है कि अलेक्जेंड्रेस्कु जैसे अपवादों का उपयोग करना (50x मंदी क्योंकि वे उपयोग catchकरते हैं else) सिर्फ गलत है। पीपीएल के लिए कहा जा रहा है जो इसे पसंद करता है जो मैं चाहता हूं कि सी ++ 22 :) कुछ इस तरह से जोड़ देगा:
(ध्यान दें कि यह मूल भाषा होनी चाहिए क्योंकि यह मूल रूप से एक से संकलक कोड बनाने वाला है)

result = attempt<lexical_cast<int>>("12345");  //lexical_cast is boost function, 'attempt'
//... is the language construct that pretty much generates function from lexical_cast, generated function is the same as the original one except that fact that throws are replaced by return(and exception type that was in place of the return is placed in a result, but NO exception is thrown)...     
//... By default std::exception is replaced, ofc precise configuration is possible
if (result)
{
     int x = result.get(); // or result.result;
}
else 
{
     // even possible to see what is the exception that would have happened in original function
     switch (result.exception_type())
     //...

}

PS यह भी ध्यान दें कि भले ही अपवाद धीमे हों ... निष्पादन के दौरान कोड के उस हिस्से में बहुत समय व्यतीत न करना एक समस्या नहीं है ... उदाहरण के लिए यदि फ्लोट डिवीजन धीमा है और आप इसे 4x बनाते हैं तेजी से कि अगर आप अपने समय का 0.3% एफपी डिवीजन कर खर्च नहीं करता है ...


0

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

संपादित करें: मैं यह नहीं कह रहा हूँ कि उनका उपयोग बिल्कुल न करें, लेकिन प्रदर्शन गहन कोड के लिए उनसे बचना सबसे अच्छा है।


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

@insilico यदि आप देखें कि मैंने क्यों कहा, तो मैंने यह नहीं कहा कि अपवादों को पूर्ण विराम का उपयोग न करें। मैंने प्रदर्शन गहन कोड निर्दिष्ट किया, यह एक सटीक मूल्यांकन है, मैं मुख्य रूप से gpgpus के साथ काम करता हूं और अगर मुझे अपवादों का उपयोग किया जाता है तो मुझे गोली मार दी जाएगी।
क्रिस मैककेबे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.