कितने नेस्टेड फ़ंक्शन कॉल कितने हैं?


15

StackOverflowException के बारे में MSDN से उद्धृत :

अपवाद जब निष्पादन ढेर हो जाता है तो फेंक दिया जाता है क्योंकि इसमें बहुत अधिक नेस्टेड विधि कॉल होते हैं।

Too manyयहाँ बहुत अस्पष्ट है। मुझे कैसे पता चलेगा कि वास्तव में बहुत सारे हैं? हजारों फ़ंक्शन कॉल? लाखों? मुझे लगता है कि यह किसी तरह से कंप्यूटर में मेमोरी की मात्रा से संबंधित होना चाहिए लेकिन क्या परिमाण के लगभग सटीक क्रम के साथ आना संभव है?

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


4
एक पुनरावर्ती फ़ंक्शन को गैर-पुनरावर्ती फ़ंक्शन में बदलना अपेक्षाकृत आसान है। बस एक पर अपने डेटा छड़ी Stack<T>
ब्रायन

1
"बहुत अधिक" कितना बड़ा है यह पूरी तरह से आपको परिभाषित करने के लिए है। .NET के लिए, का उपयोग करें editbin /stack:WHATEVER-NUMBER-YOU-LIKE yourexefile.exe
एसके-लॉजिक

जवाबों:


28

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

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


3
+1। बहुत अच्छा जवाब, मुझे इस नियम का उपयोग किया गया है लेकिन मुझे इसकी जानकारी नहीं थी।
गियोर्जियो

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

1
@ JohnR.Strohm हालाँकि ओपी ने प्रश्न .NET को टैग किया है, इसलिए AFAIK केवल 64-बिट जिटर टेल कॉल ऑप्टिमाइज़ेशन को फिलहाल करता है।
मार्क हर्ड

1
बस इसलिए कोई भ्रम नहीं है, x86 और x64 दोनों हमेशा CIL "टेल" का सम्मान करते हैं। निर्देश उपसर्ग। इसलिए संक्षेप में, .NET भूमि में, F # पूँछ-कॉल ऑप्टिमाइज़ेशन को पूरा करता है, C # नहीं करता है, और अगर यह "आसान" नहीं है तो x64 घबराना करता है। देखें blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/...
स्टीफन Swensen

1
यह सच है, लेकिन कुछ मामलों में, जैसे कि ASP.NET होस्ट करने वाले एक बदनाम IIS में, यहाँ तक कि O (log n) पुनरावृत्ति की गहराई उनके दयनीय, ​​अनुचित, हँसने योग्य छोटे स्टैक की गहराई सीमा के कारण विफल हो सकती है, जो बहुत अधिक पुनरावर्तन (या) का प्रतिपादन करती है गैर-पुनरावर्ती नेस्टेड कॉल की एक लंबी श्रृंखला भी असंभव है। चारों ओर एकमात्र रास्ता आईआईएस बाइनरी को खुद संपादित करना है।
एसके-लॉजिक

17

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

तुम भी StackOverflowExceptionएक एकल कॉल के साथ इसे फेंक कर सकते हैं यदि आप थोड़ा अपरंपरागत होने के लिए तैयार हैं:

private static unsafe void BlowUpTheStack()
{
    var x = stackalloc byte[1000000000];
    Console.WriteLine("Oh no, I've blown up the stack!");
}

दुर्भाग्य से, इस उचित डिफ़ॉल्ट का अक्सर उल्लंघन किया जाता है (जैसे, asp.net में)।
एसके-तर्क

2

चूंकि कोल कैंपबेल ने मेमोरी साइज़ और माइकल बोर्गवर्ड्ट टेल कॉल ऑप्टिमाइज़ेशन का उल्लेख किया है, मैं उन्हें कवर नहीं करूँगा।

सीपीएस के बारे में पता करने के लिए एक और बात है, जिसका उपयोग कई इंटरवॉवन फ़ंक्शन को अनुकूलित करने के लिए किया जा सकता है, जहां टेल कॉल ऑप्टिमाइज़ेशन एकल फ़ंक्शन के लिए है।

जैसा कि हमने यहां किया था , आप स्टैक का आकार बढ़ा सकते हैं और इस बात से अवगत रहें कि 64-बिट कोड 32-बिट कोड की तुलना में स्टैक को तेजी से खाता है।

ध्यान दें कि हमने F # इंटरएक्टिव के तहत उदाहरणों में से एक को स्टैक को उड़ाए बिना 40 घंटे से अधिक समय तक चलाया। हाँ, यह एक ऐसा फंक्शन कॉल था जो लगातार सफल होने तक लगातार चला।

इसके अलावा, अगर आपको यह पता लगाने के लिए कोड कवरेज करने की आवश्यकता है कि समस्याएं कहां हैं और वीएस के साथ कोड कवरेज नहीं है, तो आप उपयोग कर सकते हैं, TestDriNet.NET

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