2014-11-09 6 views
26

मैं साइमन पेटन जोन्स, एट अल द्वारा लिखे गए पेपर को पढ़ रहा था। नाम “Playing by the Rules: Rewriting as a practical optimization technique in GHC”। दूसरे खंड में, अर्थात् “ मूल विचार ” वे लिखते हैं:जीएचसी में एक व्यावहारिक अनुकूलन तकनीक के रूप में पुनर्लेखन: क्या इसकी वास्तव में आवश्यकता है?

पर विचार परिचित map समारोह, एक सूची के प्रत्येक तत्व के लिए एक समारोह लागू होता है। हास्केल में लिखा, map इस तरह दिखता है:

map f []  = [] 
map f (x:xs) = f x : map f xs 

अब मान लें कि संकलक का सामना करना पड़ता map के निम्नलिखित कॉल:

map f (map g xs) 

हम जानते हैं कि यह अभिव्यक्ति बराबर है

map (f . g) xs 

(जहां “। ” फ़ंक्शन संरचना है), और हम जानते हैं कि बाद की अभिव्यक्ति पूर्व की तुलना में अधिक कुशल है क्योंकि कोई मध्यवर्ती सूची नहीं है। लेकिन संकलक के पास ऐसा कोई ज्ञान नहीं है।

एक संभावित पुनर्जन्म यह है कि संकलक स्मार्ट होना चाहिए --- लेकिन प्रोग्रामर हमेशा उन चीजों को जानता होगा जो संकलक नहीं समझ सकते हैं। एक और सुझाव यह है: प्रोग्रामर को ऐसे ज्ञान को सीधे संकलक को संवाद करने की अनुमति दें। यही वह दिशा है जिसे हम यहां खोजते हैं।

मेरा सवाल है, हम कंपाइलर को स्मार्ट क्यों नहीं बना सकते? लेखकों का कहना है कि “ लेकिन प्रोग्रामर हमेशा उन चीजों को जानता होगा जो संकलक ” को नहीं समझ सकते हैं।

map f (map g xs) 
  1. map g xsmap f [] = [] साथ सम्मिलित है: हालांकि, वह एक मान्य जवाब क्योंकि संकलक वास्तव में पता लगा सकते हैं कि map f (map g xs)map (f . g) xs के बराबर है नहीं है, और यहाँ कैसे है।

    इसलिए map g [] = []

  2. map f (map g []) = map f []

    map f []map f [] = [] के साथ एकीकृत करता है।

    इसलिए map f (map g []) = []

  3. map g xsmap f (x:xs) = f x : map f xs के साथ एकीकृत करता है।

    इसलिए map g (x:xs) = g x : map g xs

  4. map f (map g (x:xs)) = map f (g x : map g xs)

    map f (g x : map g xs)map f (x:xs) = f x : map f xs के साथ एकीकृत करता है।

    इसलिए map f (map g (x:xs)) = f (g x) : map f (map g xs)

इसलिए हम अब नियम है:

map f (map g [])  = [] 
map f (map g (x:xs)) = f (g x) : map f (map g xs) 

आप देख सकते हैं f (g x) सिर्फ (f . g) और map f (map g xs) रिकर्सिवली बुलाया जा रहा है। यह वास्तव में map (f . g) xs की परिभाषा है। इस स्वचालित रूपांतरण के लिए एल्गोरिदम बहुत सरल लगता है। तो फिर से लिखने के नियमों के बजाय इसे लागू क्यों नहीं करें?

उत्तर

34

आक्रामक इनलाइनिंग कई बराबरता प्राप्त कर सकती है जो नियमों को फिर से लिखने के लिए कम हैं। अंतर यह है कि इनलाइनिंग "अंधा" है, इसलिए यदि आप बेहतर या बदतर हो जाएंगे, या यहां तक ​​कि अगर यह समाप्त हो जाएगा तो आप अग्रिम में नहीं जानते हैं।

हालांकि, कार्यक्रमों के बारे में बहुत अधिक स्तर के तथ्यों के आधार पर, नियमों को फिर से लिखना पूरी तरह से गैर-स्पष्ट चीजें कर सकता है। अनुकूलक को नए सिद्धांतों को जोड़ने के रूप में नियमों को फिर से लिखने के बारे में सोचें। इन्हें जोड़कर आपके पास लागू करने के लिए जटिल अनुकूलन को आसान बनाने के लिए लागू करने के लिए एक समृद्ध नियम सेट है।

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

+2

यह उपयोगी होगा अगर आप मुझे एक ठोस उदाहरण दिखा सकें नियमों को फिर से लिखना बेहतर है। –

+5

क्या आपने स्ट्रीम फ़्यूज़न पर लिंक किए गए पेपर को देखा था? –

7

मेरा एक छात्र जोहान्स बदर के बैचलर की थीसिस में उस दिशा में कुछ जांच की गई: Finding Equations in Functional Programs (PDF file)।

कुछ हद यह निश्चित रूप से संभव है करने के लिए, लेकिन

  • यह काफी मुश्किल है। इस तरह के समीकरणों को ढूंढना एक प्रमेय प्रूफर में सबूत ढूंढना मुश्किल है, और
  • यह अक्सर बहुत उपयोगी नहीं होता है, क्योंकि यह समीकरणों को ढूंढता है जो प्रोग्रामर शायद ही कभी लिखता है।

हालांकि इनलाइनिंग और संलयन के विभिन्न रूप जैसे अन्य परिवर्तनों के बाद इसे साफ करना उपयोगी है।

1

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

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

कैसे यदि आप विशेष मामले का अनुकूलन करते हैं, दो परिणामों में से एक होती है

  • कोई भी उस पर निर्भर करता है, क्योंकि वे यकीन है कि अगर यह वहाँ है या नहीं नहीं हैं।इस मामले में, आपके द्वारा उद्धृत किए गए लेख जैसे लेख
  • लोग इस पर भरोसा करना शुरू करते हैं, और अब प्रत्येक डेवलपर को याद रखना पड़ता है "इस कॉन्फ़िगरेशन में किए गए मानचित्र स्वचालित रूप से मेरे लिए तेज़ संस्करण में परिवर्तित हो जाते हैं, लेकिन अगर मैं करता हूं यह इस विन्यास में मैं नहीं करता। ' इस तरह से लोगों को भाषा का प्रयोग हेरफेर करने के लिए शुरू होता है, और वास्तव में पठनीयता को कम कर सकते हैं!

जरूरत डेवलपर्स सामान्य मामले में इस तरह अनुकूलन के बारे में सोचने के लिए के लिए, हम डेवलपर्स सरल मामले में इन अनुकूलन कर देखने की उम्मीद को देखते हुए , पहली जगह अनुकूलन की आवश्यकता को कम करना!

अब, यदि यह पता चला है कि विशेष स्थिति में आप रुचि रखते हैं तो हास्केल में विश्व कोडबेस के 2% की तरह बड़े पैमाने पर खाते हैं, तो वहां बहुत मजबूत होगा अपने विशेष केस अनुकूलन को लागू करने के लिए तर्क।

संबंधित मुद्दे