2012-10-14 19 views
12

मुझे एक बड़ी समस्या है। मेरे पास एक आम पुस्तकालय है, जिसका उपयोग पूरे प्रोजेक्ट में किया जाता है। यह लाइब्रेरी boost.spirit और boost.fusion का गहन रूप से उपयोग करती है। दुर्भाग्यवश, पुस्तकालय लगभग है। आकार में 700 एमबी। सभी boost.spirit -heavy कोड का उपयोग किया जाता है और यह अच्छी तरह से काम करता है। इसके आउटपुट आकार को कम करने के लिए क्या कदम उठाए जा सकते हैं? क्या कोई ऐसा टूल है जो यह निर्धारित करने में मदद कर सकता है कि कौन से टेम्पलेट इंस्टीटेशन अधिकांश जगह बर्बाद कर रहे हैं?टेम्पलेट-भारी सी ++ कोड के आउटपुट आकार को कैसे कम करें?

सबसे पहले, मैंने सभी भावना-जागरूक कोड को सीपीपी फ़ाइलों में स्थानांतरित करने का निर्णय लिया। दूसरा, मैं आकार के लिए अनुकूलित करने के लिए विभिन्न कंपाइलर झंडे का प्रयास करूंगा। मुझे नहीं मालूम और क्या करना है।

अद्यतन (विवरण)

मैं जीएनयू toolchain उपयोग कर रहा हूँ। विशाल पुस्तकालय वास्तव में एक स्थिर पुस्तकालय है। निष्पादन योग्य, जो इस 700 एमबी पुस्तकालय का उपयोग करता है वह आकार में 200 एमबी है। कोड का कम से कम आधा * .h फाइलों में है। कुछ boost.spirit व्याकरण (बहुत टेम्पलेट भारी चीज़) * .h फ़ाइलों में भी स्थित है।

चीयर्स!

उत्तर

5

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

  1. सुनिश्चित करें कि लाइब्रेरी के बाहर किसी भी व्याकरण/नियमों का निर्यात कभी भी नहीं किया जाता है। यदि आपके पास सामान्य include/src निर्देशिकाएं हैं, तो src निर्देशिका में उन फ़ाइलों को स्थानांतरित करें (यहां तक ​​कि हेडर)।

  2. उन सभी प्रतीकों को पुस्तकालय में आंतरिक के रूप में चिह्नित करें। उन्हें पुस्तकालय के बाहर से सुलभ नहीं होना चाहिए।आपके कंपाइलर के आधार पर विशिष्ट pragmas/विशेषताएँ हैं, gcc लुकअप पर visibility attribute: __attribute__ ((visibility ("internal")))। यह संकलक को तदनुसार अनुकूलित करने में मदद करता है, विशेष रूप से एक कंपाइलर फ़ंक्शन के कोड को उत्सर्जित कर सकता है, भले ही यह किसी दिए गए कॉल साइट पर इसे रेखांकित करता हो, बस इस फ़ंक्शन पते के मामले में। आंतरिक दृश्यता के साथ हालांकि, चूंकि यह जानता है कि कोड ऑब्जेक्ट नहीं छोड़ेगा, यह फ़ंक्शन को बढ़ा सकता है।

  3. मैं समान समारोह निकायों फ्यूज करने के लिए एक ध्वज याद करने लगते हैं लेकिन फिर से खोजने के लिए प्रतीत नहीं कर सकते हैं ...

+0

निष्पादन योग्य आकार के लिए चमत्कार 'दृश्यता' विशेषता के लिए धन्यवाद, इसके बारे में नहीं जानते। – Lazin

2

कुछ सुझाव:

  • जहां संभव हो, एक std::vector<int> और std::vector<float> ही आंतरिक संरचना के लिए होता है (एक ही टेम्पलेट instantiations पुन: उपयोग करने के लिए एक सरल रूप में की कोशिश, और काल्पनिक, उदाहरण और दोनों ही इलाज कर सकते हैं अपारदर्शी 4-बाइट ब्लब्स के रूप में उनके तत्व डेटा, इसलिए कोई दूसरे को सौंप सकता है, और केवल एक चीज रैपर के रूप में कार्य करता है जो कि सही प्रकार पर वापस आता है, ताकि वेक्टर के आंतरिक केवल एक प्रकार के लिए तत्काल हो जाएं, दो के बजाय

  • एक अलग कंपाइलर आज़माएं। कुछ कंपाइलर्स समान टेम्पलेट इंस्टॉलेशन का पुन: उपयोग करते हैं जहां यह प्रोग्राम अर्थशास्त्र को प्रभावित नहीं करेगा, जबकि अन्य अधिक रूढ़िवादी हैं।

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

लेकिन आखिरकार, ऐसा लगता है जैसे आपको कम टेम्पलेट-भारी लाइब्रेरी का उपयोग करना पड़ सकता है। (या एक सरल पार्सर लिखने से आपकी वर्तमान)

+1

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

+0

@MatthieuM। सच है, यही कारण है कि सभी कंपाइलर्स ऐसा नहीं करते हैं। यह आम तौर पर एक सुंदर सुरक्षित अनुकूलन होता है (आप अक्सर फ़ंक्शन पते की तुलना नहीं करते हैं, और जब आप करते हैं, और मुझे लगता है कि ज्यादातर मामलों में यह अमान्य है, तो यह संकलक के लिए यह काफी सरल है) - हालांकि, यह करता है टेम्पलेट-भारी कोड – jalf

2

यह यहाँ पर चर्चा की गई है: why my C++ output executable is so big?

असल में, प्रतीकों, लिंक निर्भरता, अनुकूलन के लिए आदेश डीबगिंग के लिए लग रही है और इतने पर ...

4

--ffunction-sections अपने स्वयं के क्षेत्र में प्रत्येक कार्य डाल देंगे। अपने अधिकार में उपयोगी नहीं है, लेकिन लिंकर --gc-sections के साथ अप्रयुक्त वर्गों को हटा सकता है। अब --function-segments के बिना यह केवल तभी काम करेगा जब एक संपूर्ण स्रोत फ़ाइल का उपयोग नहीं किया गया था, यानी एक पागल ग्रैन्युलरिटी के साथ।

जाहिर है आपको Matthieu द्वारा वर्णित दृश्यता विशेषता की आवश्यकता है, अन्यथा लाइब्रेरी में सभी फ़ंक्शंस दृश्यमान होने के कारण "उपयोग" किए जाते हैं।