क्या आप इसे ghci में या संकलित प्रोग्राम में चला रहे हैं? इससे बड़ा फर्क पड़ता है।
यदि ghci में है, तो ghci बाद में इसका उपयोग करना चाहते हैं तो test
के गणना मूल्य को बनाए रखेगा। आम तौर पर यह एक अच्छा विचार है, लेकिन इस मामले में जहां test
एक बड़ा मूल्य है जो किसी भी तरह से पुन: सम्मिलित करने के लिए सस्ता होगा। कितना बड़ा स्टार्टर्स के लिए यह 10^8 तत्वों की सूची है, और (64-बिट सिस्टम पर) एक सूची में प्रति तत्व 24 बाइट्स खर्च होते हैं, इसलिए यह पहले से ही 2.4 जी है। फिर मूल्यों का अंतरिक्ष उपयोग स्वयं होता है। कोई सोच सकता है कि मूल्य [1..100]
से लिया गया है, इसलिए उन्हें साझा किया जाना चाहिए और कुल में नगण्य राशि का उपयोग करना चाहिए। लेकिन सूची में मूल्य वास्तव में x
के रूप में हैं, जो a
, b
, c
और d
पर निर्भर हो सकता है, और length
सूची में मूल्यों की जांच कभी नहीं करता है क्योंकि यह इसे पार करता है। इसलिए प्रत्येक तत्व को बंद करने के रूप में दर्शाया जा रहा है जो a
, b
, c
और d
को संदर्भित करता है, जो कम से कम 8 * (4 + 1) = 40 और बाइट्स लेता है, जो हमें कुल 6.4 जी तक ले जाता है।
यह बहुत कुछ है, और जब आप डेटा के 6.4 जी आवंटित करते हैं तो कचरा कलेक्टर को बहुत सारी प्रतिलिपि करना पड़ता है, यह सब स्थायी रूप से रहता है। यह इतना लंबा लगता है, वास्तव में सूची या इसकी लंबाई की गणना नहीं करता है।
आप इस कार्यक्रम
test = [x|a<-[1..100],b<-[1..100],c<-[1..100],d<-[1..100],let x = a]
main = print $ length test
तो test
के रूप में अपनी लंबाई की गणना की जा रही है लाइव रखा जाना नहीं है, के रूप में स्पष्ट रूप से यह कभी नहीं फिर से इस्तेमाल किया जा रहा है संकलन है। तो अब जीसी के पास लगभग कोई काम नहीं है, और कार्यक्रम कुछ सेकंड में चलता है (Integer
पर ~ 10^8 सूची नोड आवंटन और गणना के लिए उचित)।
स्रोत
2015-10-12 13:21:44
यह "क्यों" प्रश्न का उत्तर नहीं देता है, लेकिन: अनुकूलन के साथ संकलित करें। मैं ghci में 25s का पालन करें; 20-एस 'के साथ संकलित जब; लेकिन '-O2' के साथ संकलित जब केवल 0.3s। –
अंतिम उत्तर 10^8 नहीं 100 क्यों है क्योंकि एक असाइनमेंट है 'चलो x = a'? – Kamel
@ कमल 'चलो x = a' सभी बाइंड्स के बाद है, इसलिए 'x' को अभी भी 10^8 बार दोहराया जाना चाहिए। –