आलसी मूल्यांकन का उपयोग हर जगह क्यों नहीं किया जाता है?


32

मैंने अभी-अभी जाना है कि आलसी मूल्यांकन कैसे काम करता है और मैं सोच रहा था: वर्तमान में उत्पादित हर सॉफ्टवेयर में आलसी मूल्यांकन क्यों लागू नहीं होता है? अभी भी उत्सुक मूल्यांकन का उपयोग क्यों?


2
यदि आप परस्पर स्थिति और आलसी मूल्यांकन का मिश्रण करते हैं तो क्या हो सकता है, इसका एक उदाहरण यहां दिया गया है। alicebobandmallory.com/articles/2011/01/01/…
जोनास

2
@ JonasElfström: कृपया, अपने संभावित क्रियान्वयन में से एक के साथ परस्पर स्थिति को भ्रमित न करें। मूल्यों की एक अनंत, आलसी धारा का उपयोग करके उत्परिवर्तित अवस्था को लागू किया जा सकता है। तब आपको उत्परिवर्तनीय चरों की समस्या नहीं होती है।
जियोर्जियो

अनिवार्य प्रोग्रामिंग भाषाओं में, "आलसी मूल्यांकन" को प्रोग्रामर से सचेत प्रयास की आवश्यकता होती है। अनिवार्य भाषाओं में सामान्य प्रोग्रामिंग ने इसे आसान बना दिया है, लेकिन यह कभी भी पारदर्शी नहीं होगा। प्रश्न के दूसरे पक्ष का उत्तर एक और प्रश्न सामने लाता है: "कार्यात्मक प्रोग्रामिंग भाषाओं का उपयोग हर जगह क्यों नहीं किया जाता है?", और वर्तमान में वर्तमान मामलों के मामले में इसका उत्तर बस "नहीं" है।
रौंग

2
कार्यात्मक प्रोग्रामिंग भाषाओं का उपयोग हर जगह एक ही कारण से नहीं किया जाता है क्योंकि हम स्क्रू पर हथौड़ों का उपयोग नहीं करते हैं, हर समस्या को आसानी से एक कार्यात्मक इनपुट में व्यक्त नहीं किया जा सकता है -> आउटपुट तरीके, उदाहरण के लिए GUI बेहतर रूप से एक अनिवार्य तरीके से व्यक्त किए जाने के लिए अनुकूल है ।
ALXGTV

इसके अलावा कार्यात्मक प्रोग्रामिंग भाषाओं के दो वर्ग हैं (या कम से कम दोनों कार्यात्मक होने का दावा करते हैं), अनिवार्य कार्यात्मक भाषाएं जैसे क्लोजर, स्काला और घोषणात्मक जैसे हास्केल, ओकेमेल।
ALXGTV

जवाबों:


38

आलसी मूल्यांकन के लिए बुक-कीपिंग ओवरहेड की आवश्यकता होती है- आपको यह जानना होगा कि क्या इसका मूल्यांकन अभी तक किया गया है और ऐसी चीजें। उत्सुक मूल्यांकन हमेशा मूल्यांकन किया जाता है, इसलिए आपको पता नहीं है। यह समवर्ती संदर्भों में विशेष रूप से सच है।

दूसरी बात यह है कि यदि आप चाहें तो बाद में इसे किसी फंक्शन ऑब्जेक्ट में पैकेजिंग द्वारा आलसी मूल्यांकन में उत्सुक मूल्यांकन में परिवर्तित करना तुच्छ है।

तीसरे, आलसी मूल्यांकन से नियंत्रण का नुकसान होता है। अगर मैं किसी डिस्क से किसी फ़ाइल को पढ़ने का मूल्यांकन करता हूं तो क्या होगा? या समय मिल रहा है? यह स्वीकार्य नहीं है।

उत्सुक मूल्यांकन अधिक कुशल और अधिक नियंत्रणीय हो सकता है, और तुच्छ रूप से आलसी मूल्यांकन में परिवर्तित किया जा सकता है। आप आलसी मूल्यांकन क्यों चाहते हैं?


10
Lazily डिस्क से एक फ़ाइल को पढ़ने वास्तव में बहुत साफ है - मेरी सरल कार्यक्रमों और लिपियों के अधिकांश के लिए, हास्केल के readFileहै वास्तव में मैं क्या जरूरत है। इसके अलावा, आलसी से उत्सुक मूल्यांकन में परिवर्तित करना बस तुच्छ है।
तिखन जेल्विस

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

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

1
@DeadMG नहीं अगर आपको इस बात की परवाह है कि आपका कोड समाप्त हो गया है या नहीं ... head [1 ..]आपको उत्सुकता से मूल्यांकन की गई शुद्ध भाषा में 1क्या देता है, क्योंकि हास्केल में यह देता है ?
अर्धवृत्त

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

17

मुख्य रूप से क्योंकि आलसी कोड और राज्य बुरी तरह से मिश्रण कर सकते हैं और कीड़े खोजने के लिए कुछ मुश्किल पैदा कर सकते हैं। यदि किसी आश्रित वस्तु की स्थिति में परिवर्तन होता है तो मूल्यांकन के समय आपकी आलसी वस्तु का मूल्य गलत हो सकता है। यह बेहतर है कि प्रोग्रामर स्पष्ट रूप से वस्तु को आलसी होने के लिए कोड दे जब वह जानता है कि स्थिति उपयुक्त है।

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


हाँ, परस्पर अवस्था + आलसी मूल्यांकन = मृत्यु। मुझे लगता है कि मेरे SICP फाइनल में हारने वाले एकमात्र बिंदु set!एक आलसी योजना दुभाषिया में उपयोग करने के बारे में थे । > :(
तिखन जेल्विस

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

14

आलसी मूल्यांकन हमेशा बेहतर नहीं होता है।

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

आलसी मूल्यांकन के बारे में अच्छी बात यह है कि यह आपको स्पष्ट कोड लिखने देता है; अनंत प्राकृतिक नंबरों की सूची को फ़िल्टर करके और उस सूची के 10 वें तत्व को ले कर 10 वाँ प्रधान स्थान प्राप्त करना आगे बढ़ने का सबसे संक्षिप्त और स्पष्ट तरीका है: (स्यूडोकोड)

let numbers = [1,2...]
fun is_prime x = none (map (y-> x mod y == 0) [2..x-1])
let primes = filter is_prime numbers
let tenth_prime = first (take primes 10)

मेरा मानना ​​है कि आलसीपन के बिना चीजों को इतनी बारीकी से व्यक्त करना काफी मुश्किल होगा।

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

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

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


क्या ओवरहेड को काफी कम करने के लिए वास्तव में चतुर कंपाइलर के लिए संभव होगा । या यहां तक ​​कि अतिरिक्त अनुकूलन के लिए आलस्य का लाभ उठाएं?
तिखन जेल्विस

3

यहाँ पेशेवरों और उत्सुक और आलसी मूल्यांकन के विपक्ष की एक छोटी तुलना है:

  • उत्सुक मूल्यांकन:

    • जरूरत से ज्यादा सामान का मूल्यांकन करने वाले संभावित ओवरहेड।

    • अनछुए, तेजी से मूल्यांकन।

  • आलसी मूल्यांकन:

    • कोई अनावश्यक मूल्यांकन नहीं।

    • मूल्य के प्रत्येक उपयोग पर बहीखाता ओवरहेड।

इसलिए, यदि आपके पास कई भाव हैं जिनका कभी मूल्यांकन नहीं करना है, तो आलसी बेहतर है; फिर भी यदि आपके पास कभी कोई अभिव्यक्ति नहीं है जिसका मूल्यांकन करने की आवश्यकता नहीं है, तो आलसी शुद्ध उपरि है।

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

नतीजतन, आलसी मूल्यांकन केवल औसत पर भुगतान नहीं करता है, उत्सुक मूल्यांकन आधुनिक कोड के लिए बेहतर फिट है।


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

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

2
"नतीजतन, आलसी मूल्यांकन केवल औसत पर भुगतान नहीं करता है, आधुनिक मूल्यांकन के लिए उत्सुक मूल्यांकन बेहतर है।"
जियोर्जियो

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

2
यह आलसी मूल्यांकन वाली भाषाओं के साथ अनुभवहीनता का एक उत्तर लगता है। उदाहरण के लिए, अनंत डेटा संरचनाओं के बारे में क्या?
एंड्रेस एफ।

3

जैसा कि @DeadMG ने कहा कि आलसी मूल्यांकन के लिए बुक-कीपिंग ओवरहेड की आवश्यकता होती है। यह उत्सुक मूल्यांकन के सापेक्ष महंगा हो सकता है। इस कथन पर विचार करें:

i = (243 * 414 + 6562 / 435.0 ) ^ 0.5 ** 3

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

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

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

सामान्य तौर पर यह उन चीजों का मूल्यांकन करने के लिए अच्छा अभ्यास है जो अक्सर जल्दी से जल्दी पहुंच जाते हैं। आलसी मूल्यांकन इस अभ्यास के साथ काम नहीं करता है। यदि आप हमेशा कुछ हासिल करेंगे, तो सभी आलसी मूल्यांकन ओवरहेड जोड़ देंगे। आलसी मूल्यांकन का उपयोग करने की लागत / लाभ कम हो जाता है क्योंकि जिस वस्तु तक पहुँचा जा सकता है, उसके एक्सेस होने की संभावना कम हो जाती है।

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

समय से पहले अनुकूलन से बचना अच्छा कोडिंग प्रथाओं के साथ संघर्ष नहीं करता है। यदि अच्छी प्रथाओं को लागू नहीं किया गया था, तो प्रारंभिक अनुकूलन में अच्छी कोडिंग प्रथाओं को लागू करना शामिल हो सकता है जैसे कि लूप से बाहर की गणना।


1
आप अनुभवहीनता से बहस कर रहे हैं। मेरा सुझाव है कि आप वाडलर द्वारा "व्हाई फंक्शनल प्रोग्रामिंग मैटर्स" पेपर पढ़ें। यह आलसी मूल्यांकन के कारण की व्याख्या करते हुए एक प्रमुख खंड को बताता है (संकेत: इसका प्रदर्शन, शुरुआती अनुकूलन या "लोड हो रहा है अनैतिक रूप से एक्सेस डेटा", और सब कुछ मॉड्यूलरता के साथ करना है)।
एंड्रेस एफ।

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

2
जैसे कि? उत्सुक मूल्यांकन का उपयोग करते समय महत्वपूर्ण प्रदर्शन लागतों की रिपोर्ट होती है (या तो अनावश्यक मूल्यांकन के रूप में लागत, साथ ही साथ कार्यक्रम गैर-समाप्ति)। लगभग किसी भी अन्य (गलत) इस्तेमाल की जाने वाली सुविधा के लिए लागत हैं, इसके बारे में सोचें। प्रतिरूपकता स्वयं लागत पर आ सकती है; मुद्दा यह है कि क्या यह इसके लायक है।
एंड्रेस एफ।

3

अगर हमें संभावित रूप से किसी मूल्य का निर्धारण करने के लिए पूरी तरह से अभिव्यक्ति का मूल्यांकन करना है तो आलसी मूल्यांकन एक नुकसान हो सकता है। कहो कि हमारे पास बूलियन मूल्यों की एक लंबी सूची है और हम यह पता लगाना चाहते हैं कि क्या ये सभी सत्य हैं:

[True, True, True, ... False]

ऐसा करने के लिए हमें सूची में मौजूद प्रत्येक तत्व को देखना होगा , चाहे वह कुछ भी हो, इसलिए मूल्यांकन में आलस्य को काटने की कोई संभावना नहीं है। हम यह निर्धारित करने के लिए एक तह का उपयोग कर सकते हैं कि सूची में सभी बूलियन मान सही हैं या नहीं। यदि हम एक तह सही का उपयोग करते हैं, जो आलसी मूल्यांकन का उपयोग करता है, तो हमें आलसी मूल्यांकन का कोई लाभ नहीं मिलता है क्योंकि हमें सूची में प्रत्येक तत्व को देखना होगा:

foldr (&&) True [True, True, True, ... False] 
> 0.27 secs

इस मामले में एक गुना दायाँ हिस्सा सख्त गुना की तुलना में बहुत धीमा होगा, जो आलसी मूल्यांकन का उपयोग नहीं करता है:

foldl' (&&) True [True, True, True, ... False] 
> 0.09 secs

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


"तो, बिंदु यह है, आपको उस कार्य का उपयोग करना चाहिए जो हाथ में काम के लिए सबसे अच्छा है।" +1
जियोर्जियो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.