मैंने हाल ही में हास्केल सीखा है, और जब संभव हो तो शुद्ध कार्यात्मक शैली को मेरे अन्य कोड पर ले जाने की कोशिश कर रहा हूं। इसका एक महत्वपूर्ण पहलू अपरिवर्तनीय, यानी स्थिरांक के रूप में सभी चरों का इलाज कर रहा है। ऐसा करने के लिए, एक अनिवार्य शैली में लूप का उपयोग करके लागू किए जाने वाले कई कंप्यूटेशंस को रिकर्सन का उपयोग करके निष्पादित किया जाना चाहिए, जो आमतौर पर आवंटन के कारण प्रत्येक फ़ंक्शन कॉल के लिए एक नया स्टैक फ्रेम आवंटित करता है। पूंछ कॉल के विशेष मामले में (जहां एक बुलाए गए फ़ंक्शन का रिटर्न वैल्यू तुरंत कैली के कॉलर पर लौटा दिया जाता है), हालांकि, इस जुर्माना को पूंछ कॉल ऑप्टिमाइज़ेशन नामक प्रक्रिया द्वारा छोड़ा जा सकता है (एक विधि में, यह किया जा सकता है ढेर को ठीक से स्थापित करने के बाद अनिवार्य रूप से एक jmp के साथ एक कॉल को बदलना)। क्या MATLAB डिफ़ॉल्ट रूप से टीसीओ निष्पादित करता है, या क्या इसे बताने का कोई तरीका है?क्या MATLAB पूंछ कॉल अनुकूलन करता है?
उत्तर
अगर मैं एक साधारण पूंछ पुनरावर्ती समारोह को परिभाषित:
function tailtest(n)
if n==0; feature memstats; return; end
tailtest(n-1);
end
और इसे कहते इतना है कि यह काफी गहरा recurse होगा:
set(0,'RecursionLimit',10000);
tailtest(1000);
तो यह रूप में ढेर फ्रेम हैं अगर नहीं लगती है बहुत सारी मेमोरी खा रही है। हालांकि, अगर मैं इसे बहुत गहरे recurse:
set(0,'RecursionLimit',10000);
tailtest(5000);
तो (मेरी मशीन, आज पर) MATLAB बस दुर्घटनाओं: प्रक्रिया unceremoniously मर जाता है।
मुझे नहीं लगता कि यह MATLAB के साथ कोई भी टीसीओ कर रहा है; वह मामला जहां एक फ़ंक्शन पूंछ स्वयं ही कॉल करता है, केवल एक ही स्थान पर, किसी भी तर्क के अलावा कोई स्थानीय चर नहीं होता है, जितना सरल हो सकता है उतना ही सरल होता है।
तो: नहीं, ऐसा प्रतीत होता है कि MATLAB कम से कम डिफ़ॉल्ट रूप से टीसीओ नहीं करता है। मैंने (अब तक) विकल्पों की तलाश नहीं की है जो इसे सक्षम कर सकती हैं। अगर कोई था तो मुझे आश्चर्य होगा।
ऐसे मामलों में जहां हम ढेर को नहीं उड़ाते हैं, रिकर्सन लागत कितनी है? बिल चेथम के जवाब पर मेरी टिप्पणी देखें: ऐसा लगता है कि समय ओवरहेड अनौपचारिक है लेकिन पागल नहीं है।
... सिवाय इसके कि बिल धोथम ने उस टिप्पणी को छोड़ने के बाद अपना जवाब हटा दिया। ठीक। इसलिए, मैंने फाइबोनैकी फ़ंक्शन का एक सरल पुनरावृत्ति कार्यान्वयन किया और एक साधारण पूंछ-पुनरावर्ती व्यक्ति, जो अनिवार्य रूप से दोनों में समान गणना कर रहा था, और उन्हें fib(60)
पर दोनों का समय दिया। पुनरावर्ती कार्यान्वयन को पुनरावर्तक से चलाने के लिए लगभग 2.5 गुना अधिक समय लगता है। निस्संदेह रिश्तेदार ओवरहेड उन कार्यों के लिए छोटा होगा जो एक अतिरिक्त से अधिक काम करते हैं और प्रति पुनरावृत्ति प्रति एक घटाव करते हैं।
(मैं भी delnan की भावना से सहमत:। प्रकार कि हास्केल में प्राकृतिक लगता है की अत्यधिक पुनरावर्ती कोड आम तौर पर MATLAB में unidiomatic होने की संभावना है)
मैटलैब में टीसीओ कठिन हो सकता है क्योंकि स्टैक फ्रेम के वर्कस्पेस से स्थानीय चर के सफाई को ऑनलेनअप के साथ दुष्प्रभाव हो सकते हैं() सुविधा। Matlab जीसीड जावा शैली नहीं है; संदर्भ संख्या या इसी तरह का उपयोग करके यह निर्धारक है। आरएआईआई का समर्थन करता है। यह निर्धारित करने के लिए कि क्या स्टैक फ्रेम एलीशन सुरक्षित था, उसे सभी स्थानीय चरों को गहराई से खोजना होगा जो पूंछ कॉल में पारित नहीं हुए थे, यह देखने के लिए कि क्या उन्होंने क्लेनअप पर कोई भी आयोजन किया है या नहीं। महंगी परीक्षण साथ ही, असाइनिन (..., 'कॉलर') या evalin (..., 'कॉलर') के मामले में कम से कम एक पैरेंट स्टैक फ्रेम को संरक्षित करने की आवश्यकता हो सकती है। माना; unidiomatic। –
बस की बिल्ली के लिए यात्रा से बचना एक अच्छा नहीं है विचार। दी गई समस्या के लिए जो भी अधिक अनुचित है उसका उपयोग करें (और व्यवहार्य - निश्चित रूप से पुनरावृत्ति पूरी तरह कार्यात्मक भाषा में व्यावहारिक नहीं है)। – delnan
उचित पूंछ-कॉल अनुकूलन के साथ, "पुनरावृत्ति से परहेज" एक समस्या बन जाती है कि आप समस्या के बारे में क्या सोचते हैं, न कि आपका समाधान कैसा प्रदर्शन करता है। यदि MATLAB टीसीओ की पेशकश नहीं करता है, तो जाहिर है, जब मुझे आवश्यकता होती है तो मैं पुनरावृत्ति का उपयोग करूंगा, लेकिन यदि ऐसा होता है तो मैं अपने सभी कोड में लगातार प्रतिमान का उपयोग करने में सक्षम हूं। –
मुझे particukar में कोई MATLAB नहीं पता, मैं आम तौर पर बोल रहा हूँ। यदि आप पाइथन को कोड कर रहे थे, और पायथन के पास टीसीओ था, तो आपको अभी भी लूप पर रिकर्सन का उपयोग नहीं करना चाहिए, क्योंकि यह मूर्खतापूर्ण नहीं है, भाषा और stdlib iterators से अधिक प्राप्त करने पर केंद्रित है, और "लगातार प्रतिमान" के संबंध में: प्रत्येक प्रतिमान के कमजोर बिंदु हैं, इसलिए किसी दिए गए समस्या को हल करने के लिए जो कुछ भी हल करें ("सर्वश्रेष्ठ" की परिभाषा में यह भी शामिल है कि यह बाकी के साथ कितनी अच्छी तरह से काम करता है)। – delnan