SPECIALIZE
प्रगामा का उपयोग कब करें और इसका प्रदर्शन लाभ क्या है।
आप संकलक एक समारोह विशेषज्ञ यदि आप एक (प्रकार वर्ग) बहुरूपी समारोह है, और उम्मीद है कि यह एक या वर्ग (ते) के कुछ उदाहरणों में अक्सर के नाम से जाना करते हैं।
विशेषज्ञता उस शब्दकोष को हटा देती है जहां इसका उपयोग किया जाता है, और अक्सर आगे अनुकूलन को सक्षम बनाता है, कक्षा सदस्य कार्यों को अक्सर रेखांकित किया जा सकता है, और वे सख्त विश्लेषण के अधीन हैं, दोनों संभावित रूप से भारी प्रदर्शन लाभ देते हैं। यदि एकमात्र अनुकूलन संभव है तो डायसोनरी लुकअप का उन्मूलन, लाभ आम तौर पर बड़ा नहीं होगा।
जीएचसी -7 के रूप में, यह संभवतः {-# INLINABLE #-}
प्रगामा को देने के लिए अधिक उपयोगी है, जो इंटरफ़ेस फ़ाइल में उपलब्ध (लगभग अपरिवर्तित, कुछ सामान्यीकृत और desugaring किया जाता है) स्रोत बनाता है, इसलिए फ़ंक्शन विशिष्ट हो सकता है और संभावित रूप से कॉल साइट पर भी रेखांकित।
RULES
का उपयोग कहां करें। मैंने लोगों को एक विशेष नियम लेने के बारे में सुना है जो फायरिंग नहीं कर रहे हैं? हम इसे कैसे देख सकते हैं?
आप देख सकते हैं कि -ddump-rule-firings
कमांड लाइन विकल्प का उपयोग करके आप कौन से नियम निकाल चुके हैं। यह आमतौर पर बड़ी संख्या में निकाल दिए गए नियमों को डंप करता है, इसलिए आपको अपने नियमों के लिए थोड़ा सा खोजना होगा।
आप का उपयोग नियम
आप विशेष प्रकार, उदाहरण के लिए एक समारोह के एक अधिक कुशल संस्करण है जब
{-# RULES
"realToFrac/Float->Double" realToFrac = float2Double
#-}
जब कुछ कार्यों विशेष तर्क है, उदा के लिए एक अधिक कुशल संस्करण के साथ प्रतिस्थापित किया जा सकता है
{-# RULES
"^2/Int" forall x. x^(2 :: Int) = let u = x in u*u
"^3/Int" forall x. x^(3 :: Int) = let u = x in u*u*u
"^4/Int" forall x. x^(4 :: Int) = let u = x in u*u*u*u
"^5/Int" forall x. x^(5 :: Int) = let u = x in u*u*u*u*u
"^2/Integer" forall x. x^(2 :: Integer) = let u = x in u*u
"^3/Integer" forall x. x^(3 :: Integer) = let u = x in u*u*u
"^4/Integer" forall x. x^(4 :: Integer) = let u = x in u*u*u*u
"^5/Integer" forall x. x^(5 :: Integer) = let u = x in u*u*u*u*u
#-}
जब सामान्य कानूनों के अनुसार अभिव्यक्ति को फिर से लिखना कोड उत्पन्न हो सकता है जो अनुकूलित करने के लिए बेहतर है, उदा।
{-# RULES
"map/map" forall f g. (map f) . (map g) = map (f . g)
#-}
उत्तरार्द्ध शैली में
RULES
की
व्यापक उपयोग base
में सूची कार्यों के लिए text
पुस्तकालय में, संलयन चौखटे में किया जाता है, उदाहरण के लिए, और, संलयन (foldr/build
संलयन) एक अलग तरह कार्यान्वित किया जाता है नियमों का उपयोग करना
किसी फ़ंक्शन के तर्क कब सख्त करना है और यह कब मदद करता है? मैं समझता हूं कि तर्क को सख्त बनाने से तर्कों को सामान्य रूप में मूल्यांकन किया जाएगा, तो मुझे सभी फ़ंक्शन तर्कों के लिए सख्तता क्यों नहीं जोड़नी चाहिए? मैं कैसे तय करूं?
एक तर्क सख्त यह सुनिश्चित करेंगे कि यह, कमजोर सिर सामान्य रूप लिए मूल्यांकन किया जाता है सामान्य रूप के लिए नहीं बनाना।
आप सभी तर्कों को सख्त नहीं बनाते हैं क्योंकि कुछ कार्यों को उनके कुछ तर्कों में गैर-सख्त होना चाहिए और कुछ तर्कों में सख्त होने पर कुछ कम कुशल हैं।
examplepartition
अनंत सूची में सब पर काम करने के लिए अपनी दूसरी बहस में गैर सख्त होना चाहिए के लिए, अधिक सामान्य हर foldr
में इस्तेमाल किया दूसरा तर्क में गैर सख्त होना चाहिए समारोह अनंत सूची पर काम करने के लिए। सीमित सूचियों पर, दूसरे तर्क में फ़ंक्शन गैर-सख्त होने से यह नाटकीय रूप से अधिक कुशल हो सकता है (foldr (&&) True (False:replicate (10^9) True)
)।
यदि आप जानते हैं कि किसी भी सार्थक काम को वैसे भी किया जा सकता है, तो तर्क का मूल्यांकन किया जाना चाहिए। कई मामलों में, जीएचसी का सख्तता विश्लेषक स्वयं ही ऐसा कर सकता है, लेकिन बिल्कुल नहीं।
एक बहुत ही सामान्य मामला लूप या पूंछ के रिकर्सन में जमाकर्ता होते हैं, जहां सख्तता जोड़ने से रास्ते में भारी मात्रा में निर्माण होता है।
मुझे सख्तता जोड़ने के लिए कोई कठोर और तेज़ नियम नहीं पता है, मेरे लिए यह अनुभव की बात है, थोड़ी देर के बाद आप सीखते हैं कि सख्तता में कौन सी जगहें मदद करने की संभावना है और कहां नुकसान पहुंचा सकता है।
अंगूठे के नियम के रूप में, छोटे डेटा (जैसे Int
) का मूल्यांकन करना समझ में आता है, लेकिन अपवाद हैं।
मैं कैसे देख सकता हूं और जांचता हूं कि मेरे पास मेरे प्रोग्राम में एक स्थान रिसाव है? एक सामान्य रिसाव क्या है जो एक अंतरिक्ष रिसाव के लिए गठन कर रहे हैं?
पहला चरण +RTS -s
विकल्प का उपयोग करना है (यदि प्रोग्राम rtsopts सक्षम से जुड़ा हुआ था)। इससे आपको पता चलता है कि कुल मिलाकर कितनी मेमोरी का उपयोग किया जाता था, और आप अक्सर इसका फैसला कर सकते हैं कि क्या आपके पास रिसाव है या नहीं। +RTS -hT
विकल्प के साथ प्रोग्राम चलाने से अधिक जानकारीपूर्ण आउटपुट प्राप्त किया जा सकता है, जो एक ढेर प्रोफ़ाइल उत्पन्न करता है जो अंतरिक्ष रिसाव को खोजने में मदद कर सकता है (साथ ही, कार्यक्रम को सक्षम rtsopts से जोड़ा जाना चाहिए)।
आगे के विश्लेषण की आवश्यकता है, कार्यक्रम की रूपरेखा को सक्षम करने पर संकलित किए जाने की आवश्यकता (पुराने GHCs में, -rtsops -prof -fprof-auto
, -fprof-auto
विकल्प उपलब्ध नहीं था, -prof-auto-all
विकल्प करीबी पत्राचार है)।
फिर आप इसे विभिन्न प्रोफाइल विकल्पों के साथ चलाते हैं और जेनरेटेड हीप प्रोफाइल देखते हैं।
दो अंतरिक्ष लीक के लिए सबसे सामान्य कारणों में
- बहुत ज्यादा आलस्य
- थोड़ा आम उपसूचक उन्मूलन बहुत ज्यादा कड़ाई
तीसरे स्थान पर शायद अवांछित साझा करने से लिया जाता है, GHC करता हैं , लेकिन यह कभी-कभी जहां भी नहीं चाहता था, लंबी सूची सूचीबद्ध करता है।
रिसाव के कारण को खोजने के लिए, मुझे फिर से कोई कठोर और तेज़ नियम नहीं पता है, और कभी-कभी, एक स्थान पर सख्तता जोड़कर या किसी अन्य में आलस्य जोड़कर एक रिसाव तय किया जा सकता है।
मैं कैसे देख सकता हूं कि बहुत आलसीपन में कोई समस्या है या नहीं? मैं हमेशा ढेर प्रोफाइलिंग की जांच कर सकता हूं लेकिन मैं जानना चाहता हूं कि सामान्य कारण, उदाहरण और पैटर्न क्या हैं जहां आलस्य दर्द होता है?
आम तौर पर, आलस्य तलाश है जहां परिणाम संवर्द्धित का निर्माण किया जा सकता है, और अवांछित से पहले प्रक्रिया पूरी हो जाने, छोड़ दिया परतों में या आम तौर पर पूंछ पुनरावर्ती कार्यों में की तरह है, जहां परिणाम का कोई हिस्सा नहीं दिया जा सकता है।
आरएचडब्ल्यू सी 25? http://book.realworldhaskell.org/read/profiling-and-optimization.html –
@ डॉनस्टवार्ट धन्यवाद .. मैंने पहले से ही आरडब्ल्यूएच पढ़ा है .. समस्या यह है कि मुझे पता है कि वे क्या करते हैं लेकिन मेरे पास कोई अंतर्ज्ञान नहीं है और जहां उनका उपयोग महत्वपूर्ण है और महत्वपूर्ण नहीं है। मैंने इस प्रश्न से मेरी समझ को और बढ़ाने के लिए अन्य स्रोतों को खोजने के लिए कहा। – Satvik