2009-02-23 10 views
7

मैं प्रोग्रामिंग भाषा के बारे में और सोच रहा था जिसे मैं डिजाइन कर रहा हूं। और मैं सोच रहा था, मैं किस तरह से संकलन समय कम कर सकता हूं?एक प्रोग्रामिंग भाषा संकलन समय को कम करने के लिए कैसे?

+0

वह अभी भी इसे डिजाइन कर रहा है .. थोड़ा धैर्य रखें ..;) – p4bl0

उत्तर

1

यहाँ एक शॉट है .. वृद्धिशील संकलन

उपयोग अपने toolchain यह समर्थन करता है तो। (बनाना, दृश्य स्टूडियो, आदि)।

उदाहरण के लिए, जीसीसी/मेक में, यदि आपके पास संकलन करने के लिए कई फ़ाइलें हैं, लेकिन केवल एक फ़ाइल में परिवर्तन करें, तो केवल एक फ़ाइल संकलित हो।

+0

जब तक यह एक हेडर फ़ाइल न हो। फैक्टरिंग में थोड़ा सा प्रयास करना अक्सर लायक होता है। एच फाइलें ताकि वे अक्सर नहीं बदल सकें। एक विरासत परियोजना है जिसे हमने अनावश्यक रूप से एक हेडर फ़ाइल में डेटा संग्रहीत किया है जिसका उपयोग हर जगह किया जाता है। वहां कोई वृद्धिशील संकलन लाभ नहीं है। – Edmund

+0

उह, मुझे लगता है कि हेडर फाइल संकलित नहीं हैं .. जैसे, यदि आप विज़ुअल सी ++ में हेडर फ़ाइल को संकलित करने का प्रयास करते हैं, तो आपको एक संदेश मिलता है "इस एक्सटेंशन से जुड़े कोई संकलन उपकरण नहीं।" वैसे भी, यह सही है, लेकिन केवल सी/सी ++ के लिए, शायद .. – krebstar

3

मैं अपने संकलन समय को कम करने के तरीके क्या कर सकता हूं?

  • कोई संकलन (व्याख्या की भाषा)
  • देरी से है (बस समय में) संकलन
  • इंक्रीमेंटल संकलन
  • precompiled शीर्ष लेख फ़ाइलें
+0

हमने कुछ साल पहले वीएस 6 के साथ एक परीक्षण किया था, और 15minute संकलन समय के साथ हमारी बड़ी परियोजना वास्तव में लगभग 5 सेकंड * लंबा * प्रीकंपील्ड हेडर के साथ संकलित करने के लिए फाइलें चालू –

+0

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

+0

वीएस 6 आईएमओ का उपयोग करके आप प्रीकंपील्ड हेडर के लिए 'ऑटो' का उपयोग नहीं कर सकते हैं: इसके बजाय आपको यह कहना होगा कि * .cpp फ़ाइल उन्हें उत्पन्न करती है (यानी "stdafx.cpp") और कितने हेडर प्रीकंपल किए गए हैं। – ChrisW

0

यह क्या भाषा/आप मंच 'पर निर्भर करता है के लिए प्रोग्रामिंग फिर से। .NET विकास के लिए, आपके समाधान में मौजूद परियोजनाओं की संख्या को कम करें।

0

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

+0

मैंने अपने उत्तर में भी इसका उल्लेख किया। अगर कोई अभी भी ऐसा करता है तो मैं भी उत्सुक हूं। –

1

एफिल जैसे उपकरणों के साथ वितरित संकलन इस्तेमाल कर सकते हैं जमे हुए के विभिन्न राज्यों की एक विचार था, और कंपाइल जरूरी मतलब नहीं था कि पूरी कक्षा recompiled किया गया था।

आप कितने संगत मॉड्यूल को तोड़ सकते हैं, और आप उन्हें ट्रैक रखने के लिए कितना ख्याल रखते हैं?

2

अधिकांश भाषाओं में (सी ++ के अलावा अन्य सभी अच्छी तरह से अच्छी तरह से), व्यक्तिगत संकलन इकाइयों को संकलित करना काफी तेज़ है।

बाध्यकारी/लिंकिंग अक्सर धीमा होता है - लिंकर को केवल एक इकाई के बजाय पूरे कार्यक्रम का संदर्भ देना होता है।

सी ++ के रूप में पीड़ित है - जब तक कि आप पीआईएमपीएल मुहावरे का उपयोग न करें - इसके लिए प्रत्येक ऑब्जेक्ट के कार्यान्वयन विवरण और क्लाइंट कोड संकलित करने के लिए सभी इनलाइन फ़ंक्शंस की आवश्यकता होती है।

जावा (बाइटकोड का स्रोत) पीड़ित है क्योंकि व्याकरण वस्तुओं और वर्गों को अलग नहीं करता है - आपको यह देखने के लिए फू क्लास लोड करना होगा कि Foo.Bar.Baz बार स्थिर क्षेत्र द्वारा संदर्भित ऑब्जेक्ट का बाज़ फ़ील्ड है या नहीं फू क्लास, या Foo.Bar क्लास का एक स्थिर क्षेत्र। आप दोनों के बीच फू क्लास के स्रोत में परिवर्तन कर सकते हैं, और क्लाइंट कोड के स्रोत को नहीं बदल सकते हैं, लेकिन फिर भी क्लाइंट कोड को पुन: संकलित करना होगा, क्योंकि बाइटकोड दो रूपों के बीच अंतर करता है, भले ही वाक्यविन्यास नहीं करता है । AFAIK पायथन बाइटकोड दो के बीच अंतर नहीं करता है - मॉड्यूल उनके माता-पिता के सच्चे सदस्य हैं।

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

सी अगर आप प्रीप्रोसेसर का बहुत उपयोग करते हैं तो पीड़ित है, लेकिन वास्तविक संकलन तेज है; सी ++ से बेहतर कार्यान्वयन को छिपाने के लिए सी कोड का अधिकांश typedef struct _X* X_ptr का उपयोग करता है - एक सी हेडर आसानी से टाइप किए गए और कार्य घोषणाओं को आसानी से शामिल कर सकता है, जिससे बेहतर encapsulation प्रदान किया जा सकता है।

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

0

एक साधारण एक: सुनिश्चित करें कि संकलक मूल रूप से बहु-कोर CPU का लाभ उठा सकता है।

10

आपकी मुख्य समस्या आज I/O है। आपका सीपीयू मुख्य स्मृति की तुलना में कई गुना तेज है और हार्ड डिस्क तक पहुंचने से स्मृति लगभग 1000 गुना तेज है।

तो जब तक आप स्रोत कोड के लिए व्यापक अनुकूलन नहीं करते हैं, तो सीपीयू डेटा को पढ़ने या लिखने के लिए अधिकतर समय व्यतीत करेगा।

इन नियमों का प्रयास करें:

  1. अपने संकलक डिजाइन कई स्वतंत्र चरणों में काम करने के लिए। लक्ष्य प्रत्येक चरण को एक अलग थ्रेड में चलाने में सक्षम होना है ताकि आप बहु-कोर CPUs का उपयोग कर सकें। यह पूरे संकलन प्रक्रिया को समानांतर करने में भी मदद करेगा (यानी एक ही समय में एक से अधिक फाइलों को संकलित करने में मदद करेगा)

    यह आपको कई स्रोत फ़ाइलों को पहले से लोड करने और उन्हें प्रीप्रोसेस करने की अनुमति देगा ताकि वास्तविक संकलन चरण तेजी से काम कर सके।

  2. फ़ाइलों को स्वतंत्र रूप से संकलित करने की अनुमति देने का प्रयास करें। उदाहरण के लिए, प्रोजेक्ट के लिए "गायब प्रतीक पूल" बनाएं। गुम प्रतीकों को इस तरह संकलित विफलताओं का कारण नहीं बनना चाहिए। अगर आपको कहीं गायब प्रतीक मिल जाए, तो इसे पूल से हटा दें। जब सभी फाइलों को संकलित किया गया है, तो जांचें कि पूल खाली है।

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

  4. पृष्ठभूमि में संकलित करें। एक कंपाइलर प्रक्रिया शुरू करें जो परिवर्तन के लिए प्रोजेक्ट निर्देशिका की जांच करती है और जैसे ही उपयोगकर्ता फ़ाइल सहेजता है उन्हें संकलित करता है। इस तरह, आपको केवल हर चीज के बजाय कुछ फ़ाइलों को संकलित करना होगा। लंबे समय तक, आप अधिक संकलित करेंगे लेकिन उपयोगकर्ता के लिए, कारोबार का समय बहुत छोटा होगा (= समय उपयोगकर्ता को तब तक इंतजार करना होगा जब तक कि वह बदलाव के बाद संकलित परिणाम चला नहीं सके)।

  5. "बस समय" कंपाइलर का उपयोग करें (यानी जब फ़ाइल का उपयोग किया जाता है, तो फ़ाइल को संकलित करें, उदाहरण के लिए आयात विवरण में)। परियोजनाओं को तब स्रोत रूप में वितरित किया जाता है और पहली बार चलाने पर संकलित किया जाता है। पाइथन यह करता है। इसे करने के लिए, आप अपने कंपाइलर की स्थापना के दौरान लाइब्रेरी को प्रीकंपाइल कर सकते हैं।

  6. शीर्षलेख फ़ाइलों का उपयोग न करें। यदि आपको करना है तो सभी जानकारी को एक ही स्थान पर रखें और स्रोत से हेडर फाइलें जेनरेट करें।हो सकता है कि हेडर फ़ाइलों को केवल स्मृति में रखें और उन्हें डिस्क पर कभी भी न सहेजें।

+0

यह अच्छा है, लेकिन आपने सबसे महत्वपूर्ण बात छोड़ दी: फ़ाइल I/O। –

+0

@ david.pfx: फ़ाइल I/O एक दी गई समस्या है। नियमों के बाद एक प्रक्रिया तैयार होगी जो कम से कम I/O पर निर्भर करती है। –

+0

जैसा कि मैंने कहा, उत्तर में बहुत अच्छे विचार हैं लेकिन यदि आप स्पष्ट रूप से I/O को गति देने के तरीकों को खोजने पर ध्यान केंद्रित नहीं करते हैं, तो प्रदर्शन का पालन नहीं किया जाएगा। इसे अलग-अलग रखने के लिए, यदि आपका कंपाइलर I/O बाध्य करता है तो चालाक थ्रेडिंग या कैशिंग में से कोई भी कोई फर्क नहीं पड़ता। मुझे लगता है कि उस बिंदु पर विचार करके आपका जवाब सुधार जाएगा। –

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

यह कितना गंभीर है?

जब तक सिंटैक्स बहुत ही मजबूत नहीं हो जाता है, तो पार्सर इनपुट फ़ाइल वर्णों के माध्यम से केवल अनुक्रमणित करने से 10-100 गुना धीमी गति से चलाने में सक्षम होना चाहिए।

इसी प्रकार, कोड जनरेशन आउटपुट स्वरूपण द्वारा सीमित होना चाहिए।

जब तक आप एक बड़ा, गंभीर कंपाइलर नहीं कर रहे हैं, तब तक आप किसी भी प्रदर्शन समस्या को मार नहीं सकते हैं, जो कई शीर्षलेख फ़ाइलों के साथ मेगा लाइन ऐप्स को संभालने में सक्षम है।

फिर आपको प्रीकंपील्ड हेडर, ऑप्टिमाइज़ेशन पास और लिंकिंग के बारे में चिंता करने की आवश्यकता है।

3

मैंने स्वयं एक कंपाइलर लागू किया है, और लोगों ने इसे सैकड़ों स्रोत फ़ाइलों को खिलाने के लिए बैच शुरू करने के बाद इसे देखने के लिए समाप्त हो गया। मुझे काफी पता चला कि मुझे क्या पता चला।

यह पता चला है कि सबसे महत्वपूर्ण चीज जिसे आप अनुकूलित कर सकते हैं वह आपके व्याकरण नहीं है। यह आपके व्याख्यात्मक विश्लेषक या आपके पार्सर नहीं है। इसके बजाए, गति के मामले में सबसे महत्वपूर्ण बात वह कोड है जो डिस्क से आपकी स्रोत फ़ाइलों में पढ़ती है। I/O की डिस्क धीमी है। वाकई धीमा। डिस्क I/Os की संख्या से आप अपने कंपाइलर की गति को बहुत अधिक माप सकते हैं।

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

मैंने इस बारे में गानाट (जीसीसी के एडा कंपाइलर) को बनाए रखने वाले प्रमुख लोगों में से एक के साथ बात की, और उसने मुझे बताया कि वह वास्तव में राम डिस्क पर जो कुछ भी कर सकता था उसे रखने के लिए इस्तेमाल करता था ताकि उसकी फ़ाइल I/O वास्तव में केवल राम पढ़ता है और लिखता है।

+0

मैं एक फ़ाइल के बजाय नामित पाइप का उपयोग कर सोच रहा था और इसे रैम में रखने के अन्य तरीकों से सोच रहा था। मैं लिंकिंग में सुधार करने के तरीके के बारे में सोच नहीं सकता था। क्या मैं आपको [email protected] gmail.com ईमेल करने के लिए प्राप्त कर सकता हूं मेरे पास आपके लिए बहुत सारे प्रश्न हैं। –

+0

वास्तव में चीजों को मापने का मौका मिलने से पहले मैं आपके प्रयासों से गुजरना नहीं चाहता हूं। समयपूर्व अनुकूलन और क्या नहीं। बस बफर एपीआई के साथ प्रतिस्थापित करने के लिए पर्याप्त लेक्सर मॉड्यूलर के सामने का अंत सुनिश्चित करना सुनिश्चित करें। –

+1

बिल्कुल सही। अधिकांश भाषाओं के लिए फ़ाइल I/O समय (इनपुट और आउटपुट) पूरी तरह से आपके द्वारा किए गए सभी कार्यों पर हावी है। लेक्सर कुछ योगदान भी देता है। बाकी सब कुछ एक दूर तीसरा है। –

1

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

0

मैंने संकलन समय को कम करने के लिए बहुत अधिक काम नहीं देखा है। लेकिन कुछ विचारों को ध्यान में आता है:

  1. व्याकरण को सरल रखें। कनवॉल्यूटेड व्याकरण आपके संकलन समय को बढ़ाएगा।
  2. समांतरता का उपयोग करने का प्रयास करें, या तो मल्टीकोर जीपीयू या सीपीयू का उपयोग करें।
  3. बेंचमार्क एक आधुनिक कंपाइलर और देखें कि बाधाएं क्या हैं और आप उनसे बचने के लिए कंपाइलर/भाषा में क्या कर सकते हैं।

जब तक आप एक अति विशिष्ट भाषा लिख ​​रहे हैं, समय संकलन नहीं वास्तव में एक मुद्दा ..

0

निर्माण प्रणाली है कि चूसना नहीं करता है!

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

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

2

यहाँ कुछ प्रदर्शन चाल है कि हम संकलन गति को मापने के द्वारा सीखा है कर रहे हैं और यह प्रभावित करता है क्या: कोड के लिए आईआर, आईआर अक्षरों:

  • लिखें दो-पास संकलक। (-> एएसटी -> आईआर - यह एक तीन -pass संकलक कि पात्रों चला जाता है लिखने के लिए आसान है> कोड है, लेकिन यह जितनी जल्दी नहीं है।)

  • एक परिणाम के रूप में, एक अनुकूलक नहीं है; एक तेज अनुकूलक लिखना मुश्किल है।

  • मूल मशीन कोड के बजाय बाइटकोड उत्पन्न करने पर विचार करें। Lua के लिए वर्चुअल मशीन एक अच्छा मॉडल है।

  • एक रैखिक-स्कैन रजिस्टर आवंटक या सरल रजिस्टर आवंटक का प्रयास करें जो फ्रेज़र और हैंनसन lcc में उपयोग किया जाता है।

  • एक साधारण कंपाइलर में, व्याख्यात्मक विश्लेषण अक्सर सबसे बड़ी प्रदर्शन बाधा है। यदि आप सी या सी ++ कोड लिख रहे हैं, तो re2c का उपयोग करें। यदि आप एक और भाषा का उपयोग कर रहे हैं (जो आपको अधिक सुखद लगेगा), पेपर aboug re2c पढ़ें और सीखे गए पाठों को लागू करें।

  • अधिकतम मंच, या संभवतः iburg का उपयोग कर कोड उत्पन्न करें।

  • आश्चर्य की बात है कि, जीएनयू असेंबलर कई कंपाइलरों में एक बाधा है। यदि आप सीधे बाइनरी उत्पन्न कर सकते हैं, तो ऐसा करें। या New Jersey Machine-Code Toolkit देखें।

  • जैसा ऊपर बताया गया है, #include जैसी किसी भी चीज़ से बचने के लिए अपनी भाषा डिज़ाइन करें। या तो कोई इंटरफ़ेस फ़ाइलों का उपयोग करें या अपनी इंटरफ़ेस फ़ाइलों को प्रीकंपाइल करें।यह रणनीति नाटकीय रूप से लेक्सर पर बोझ को कम कर देती है, जैसा कि मैंने कहा था अक्सर अक्सर सबसे बड़ी बाधा है।

+0

आईआर का मतलब क्या है? मैं अब इस जानकारी को देख रहा हूं, क्या अब कोई समस्या नहीं है? मैंने सोचा कि आईओ मुख्य समस्या थी (जैसा कि आपके विश्लेषण में कई फाइलों को पढ़ा गया है, वास्तविक जटिलता नहीं)। मेरी भाषा मैं जटिल होने की योजना बना रहा हूं। –

+0

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

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

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