डायनामिक रूप से टाइप की गई भाषा के लिए कंपाइलर लिखने से जुड़ी चुनौतियाँ क्या हैं?


9

में इस बात , गुइडो van Rossum, बात कर (27:30) अजगर कोड के लिए एक संकलक लिखने के प्रयासों के बारे में है यह कह रही है पर टिप्पणी:

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

पायथन जैसी गतिशील रूप से टाइप की गई भाषा के लिए कंपाइलर लिखने से जुड़ी (संभव) चुनौतियाँ क्या हैं?


इस मामले में डायनामिक टाइपिंग लगभग सबसे बड़ा मुद्दा नहीं है। अजगर के लिए यह एक गतिशील स्कूपिंग है।
SK-तर्क

यह ध्यान देने योग्य है कि अन्य लोगों ने तर्क दिया है कि प्लेटफ़ॉर्म में डायनामिक टाइपिंग का निर्माण करना सही उत्तर है। Microsoft ने इस कारण से बहुत सारे पैसे DLR में डाल दिए- और दशकों से NeXT / Apple उस बैंडवैगन पर आधा रहा है। वह CPython की मदद नहीं करता है, लेकिन IronPython साबित करता है कि आप प्रभावी रूप से Python को संकलित कर सकते हैं, और PyPy साबित करता है कि आपको नहीं करना है।
10

2
@ पायथन में एसके-लॉजिक डायनेमिक स्कूपिंग? पिछले मैंने जाँच की, भाषा में सभी निर्माण शाब्दिक स्कूपिंग का उपयोग करते हैं।

1
@ एसके-तर्क आप गतिशील रूप से कोड बना सकते हैं और इसे निष्पादित कर सकते हैं, लेकिन यह कोड लेक्सिक रूप से स्कोप भी चलता है। पायथन कार्यक्रम में हर एक चर के लिए, आप आसानी से यह निर्धारित कर सकते हैं कि एक चर का दायरा केवल एएसटी का निरीक्षण करके है। आप execबयान के बारे में सोच रहे होंगे , जो 3.0 से चला गया है और इसलिए मेरे विचार से बाहर है (और शायद गुइडो का, जैसा कि 2012 से बात है)। क्या आप एक उदाहरण दे सकते हैं? और "डायनेमिक स्कूपिंग" की आपकी परिभाषा, अगर यह [मेरा अलग] (en.wikipedia.org/wiki/Dynamic_scoping) है।

1
@ एसके-तर्क केवल एक चीज जो मेरे लिए एक कार्यान्वयन विवरण है, वह है locals()कॉल पर जारी रखने के मूल्य को वापस करने के लिए परिवर्तन locals। क्या लागू किया गया है और निश्चित रूप से कार्यान्वयन विस्तार नहीं है, यह भी नहीं है कि प्रत्येक चर को किस दायरे में देखा जा सकता है localsया नहीं globalsबदल सकता है। चर के हर एक उपयोग के लिए, जिस दायरे को संदर्भित किया जाता है वह सांख्यिकीय रूप से निर्धारित होता है। यह निश्चित रूप से lexically scoped बनाता है। (और btw, evalऔर execनिश्चित रूप से विवरण लागू नहीं कर रहे हैं - मेरे जवाब को देखो!)

जवाबों:


16

आपने अपने प्रश्न को पुन: प्रकाशित करने में गुइडो के कथन की देखरेख की। समस्या डायनामिक-टाइप की गई भाषा के लिए कंपाइलर नहीं लिख रही है। समस्या एक है जो लिख रही है (मानदंड 1) हमेशा सही होता है, (मापदंड 2) गतिशील टाइपिंग रखता है, और (मापदंड 3) कोड की एक महत्वपूर्ण राशि के लिए काफी तेज है।

पायथन के 90% (मानदंड 1) को लागू करना आसान है और इस पर लगातार तेज़ रहना चाहिए। इसी तरह, स्टैटिक टाइपिंग (फेलिंग मानदंड 2) के साथ तेज़ पायथन वेरिएंट बनाना आसान है। 100% को लागू करना भी आसान है (एक भाषा को लागू करना जो जटिल है कि आसान है), लेकिन अभी तक इसे लागू करने का हर आसान तरीका अपेक्षाकृत धीमी गति से निकलता है (मानदंड 3 विफल हो रहा है)।

एक दुभाषिया प्लस JIT को लागू करना जो सही है, पूरी भाषा को लागू करता है, और कुछ कोड के लिए तेज़ होता है संभव है, हालांकि काफी कठिन (cf. PyPy) और केवल इसलिए यदि आप JIT संकलक के निर्माण को स्वचालित करते हैं (साइको इसके बिना किया था) , लेकिन यह बहुत ही सीमित था कि यह किस कोड में तेजी ला सकता है)। लेकिन ध्यान दें कि यह स्पष्ट रूप से दायरे से बाहर है, क्योंकि हम स्थैतिक के बारे में बात कर रहे हैं(उर्फ आगे-आगे) संकलनकर्ता। मैं केवल यह बताने के लिए इसका उल्लेख करता हूं कि इसका दृष्टिकोण स्थिर संकलक के लिए काम क्यों नहीं करता (या कम से कम कोई मौजूदा प्रतिसाद नहीं है): इसे पहले प्रोग्राम की व्याख्या और निरीक्षण करना होगा, फिर लूप के विशिष्ट पुनरावृत्ति (या किसी अन्य रैखिक कोड) के लिए कोड उत्पन्न करना होगा। पथ), फिर उस विशिष्ट पुनरावृत्ति (या कम से कम, सभी संभावित पुनरावृत्तियों के लिए नहीं) के लिए मान्यताओं के आधार पर उस नरक से बाहर का अनुकूलन करें। उम्मीद यह है कि उस कोड के कई बाद के निष्पादन भी अपेक्षा से मेल खाएंगे और इस प्रकार अनुकूलन से लाभान्वित होंगे। शुद्धता सुनिश्चित करने के लिए कुछ (अपेक्षाकृत सस्ते) चेक जोड़े जाते हैं। यह सब करने के लिए, आपको इस बात का अंदाजा होना चाहिए कि किस चीज के लिए विशेषज्ञ होना चाहिए, और वापस आने के लिए एक धीमी लेकिन सामान्य कार्यान्वयन। एओटी संकलक के पास न तो है। वे विशेषज्ञ नहीं कर सकते सब परकोड के आधार पर वे नहीं देख सकते हैं (उदाहरण के लिए गतिशील रूप से लोड किया गया कोड), और लापरवाही से विशेषज्ञता का अर्थ है अधिक कोड उत्पन्न करना, जिसमें कई समस्याएं हैं (आईकैश उपयोग, बाइनरी आकार, संकलन समय, अतिरिक्त शाखाएं)।

एओटी कंपाइलर को लागू करना जो पूरी भाषा को सही ढंग से लागू करता है वह भी अपेक्षाकृत आसान है: इस कोड के साथ खिलाए जाने पर इंटरप्रेटर क्या करेगा इसके लिए रनटाइम में कॉल करने वाला कोड जनरेट करें। Nuitka (ज्यादातर) ऐसा करता है। हालाँकि, इससे बहुत अधिक प्रदर्शन लाभ नहीं मिलता है (मानदंड 3 को विफल करना), जैसा कि आपको अभी भी एक दुभाषिया के रूप में उतना ही अनावश्यक काम करना है, सी कोड के ब्लॉक को बायटेकोड भेजने के लिए बचाएं जो आपको संकलित करता है, लेकिन क्या। यह केवल एक छोटी सी लागत है - काफी महत्वपूर्ण एक मौजूदा दुभाषिया में अनुकूलन के लायक है, लेकिन अपनी समस्याओं के साथ एक पूरी नई कार्यान्वयन का औचित्य साबित करने के लिए पर्याप्त महत्वपूर्ण नहीं है।

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

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


4

सबसे कठिन समस्या यह पता लगाना है कि किसी भी समय सब कुछ किस प्रकार का है।

सी या जावा जैसी स्थिर भाषा में, एक बार जब आपने प्रकार की घोषणा देख ली है, तो आप जानते हैं कि वह वस्तु क्या है और यह क्या कर सकती है। यदि एक चर घोषित किया जाता है int, तो यह पूर्णांक होता है। उदाहरण के लिए, यह एक कॉल करने योग्य फ़ंक्शन संदर्भ नहीं है।

पायथन में, यह हो सकता है। यह भयानक अजगर है, लेकिन कानूनी है:

i = 2
x = 3 + i

def prn(s):
    print(s)

i = prn
i(x)

अब, यह उदाहरण बहुत मूर्खतापूर्ण है, लेकिन यह सामान्य विचार दिखाता है।

अधिक वास्तविक रूप से, आप उपयोगकर्ता द्वारा परिभाषित फ़ंक्शन के साथ बिल्ट-इन फ़ंक्शन को बदल सकते हैं जो कुछ अलग करता है (जैसे एक संस्करण जो आपके कॉल करने पर इसके तर्कों को लॉग करता है)।

PyPy कोड का वास्तव में क्या करता है, यह देखने के बाद जस्ट-इन-टाइम संकलन का उपयोग करता है, और इससे PyPy चीजों को गति देता है। PyPy एक लूप देख सकता है, और सत्यापित कर सकता है कि हर बार लूप चलता है, चर fooहमेशा एक पूर्णांक होता है; तब PyPy fooलूप के माध्यम से हर पास के प्रकार को देखने वाले कोड को दूर कर सकता है , और अक्सर पायथन ऑब्जेक्ट से छुटकारा भी पा सकता है जो पूर्णांक का प्रतिनिधित्व करता है, और fooबस CPU पर एक रजिस्टर में बैठे नंबर बन सकता है। यह कैसे PyPy CPython से तेज हो सकता है; CPython टाइप लुकअप जितनी तेजी से करता है, लेकिन लुकअप भी उतना तेज नहीं है।

मुझे विवरण नहीं पता है, लेकिन मुझे याद है कि अनलडेन स्वॉल नामक एक परियोजना थी जो पायथन (एलएलवीएम का उपयोग करके) को गति देने के लिए स्थैतिक संकलक तकनीक को लागू करने की कोशिश कर रही थी। आप Google को अनलाडेन स्वॉलो के लिए खोज सकते हैं और देख सकते हैं कि क्या आप इस बात की चर्चा पा सकते हैं कि यह क्यों काम नहीं किया जैसा कि उन्होंने उम्मीद की थी।


अनलडेन स्वॉलोज़ स्थैतिक संकलन या स्थिर प्रकारों के बारे में नहीं था; अंततः जा रहा है प्रभावी ढंग से CPython दुभाषिया को पोर्ट करने के लिए, अपने सभी डायनेमिक-नेस के साथ, LLVM को, एक फैंसी नई JIT (जैसे तोता, या DLR के लिए .NET… या PyPy, वास्तव में) के साथ, वास्तव में, हालांकि वे वास्तव में समाप्त हो गए थे सीपीथॉन के भीतर बहुत से स्थानीय अनुकूलन पाए गए (जिनमें से कुछ ने इसे मेनलाइन 3.x में बनाया)। Shedskin संभवत: वह परियोजना है जिसके बारे में आप सोच रहे थे कि स्थैतिक रूप से इस्तेमाल किए जाने वाले स्थैतिक प्रकार का अनुमान Python (हालांकि C ++ के लिए, सीधे देशी कोड के लिए नहीं)।
10

Unladen Swallow के लेखकों में से एक, Reid Kleckner ने एक Unladen Swallow Retrospective पोस्ट की , जो इस संदर्भ में पढ़ने लायक हो सकती है, हालांकि वास्तव में यह तकनीकी लोगों की तुलना में प्रबंधन और प्रायोजन चुनौतियों के बारे में अधिक है।
गाली

0

जैसा कि अन्य उत्तर में कहा गया है, प्रमुख समस्या प्रकार की जानकारी का पता लगाना है। उस हद तक आप वैधानिक रूप से कर सकते हैं, आप सीधे अच्छे कोड उत्पन्न कर सकते हैं।

लेकिन फिर भी अगर आप इसे वैधानिक रूप से नहीं कर सकते हैं, तब भी आप वास्तविक समय की जानकारी प्राप्त करने के लिए, रनटाइम के समय, उचित कोड उत्पन्न कर सकते हैं। यह जानकारी अक्सर स्थिर हो जाती है, या किसी विशेष कोड बिंदु पर किसी विशेष इकाई के लिए कुछ अलग मान है। स्व प्रोग्रामिंग भाषा आक्रामक क्रम प्रकार संग्रह और रनटाइम कोड पीढ़ी के विचारों के कई बीड़ा उठाया है। इसके विचारों का व्यापक रूप से जावा और C # जैसे आधुनिक JIT- आधारित संकलक में उपयोग किया जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.