C ++ संकलन समय को तेज करने के लिए क्या तकनीकों का उपयोग किया जा सकता है?


249

C ++ संकलन समय को तेज करने के लिए क्या तकनीकों का उपयोग किया जा सकता है?

यह सवाल कुछ टिप्पणियों में स्टैक ओवरफ्लो प्रश्न C ++ प्रोग्रामिंग शैली में आया , और मुझे यह सुनने में दिलचस्पी है कि क्या विचार हैं।

मैंने एक संबंधित प्रश्न देखा है, C ++ संकलन में इतना समय क्यों लगता है? , लेकिन यह कई समाधान प्रदान नहीं करता है।


1
क्या आप हमें कुछ संदर्भ दे सकते हैं? या आप बहुत सामान्य उत्तरों की तलाश कर रहे हैं?
पाइरोलॉजिकल डिक्लेरेशन

1
इस सवाल के बहुत समान: stackoverflow.com/questions/364240/…
एडम रोसेनफील्ड

सामान्य उत्तर मुझे कई लोगों द्वारा लिखा गया एक बहुत बड़ा कोड बेस मिला है। हमला करने के तरीके पर विचार अच्छा होगा। और यह भी, नए लिखित कोड के लिए संकलन शीघ्र रखने के सुझाव दिलचस्प होंगे।
स्कॉट लैंगहम

ध्यान दें कि अक्सर निर्माण समय का एक प्रासंगिक हिस्सा संकलक द्वारा उपयोग नहीं किया जाता है, लेकिन निर्माण स्क्रिप्ट द्वारा
thi gg

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

जवाबों:


257

भाषा तकनीक

पिंपल मुहावरा

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

आगे की घोषणा

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

आई / ओ धाराओं विशेष रूप से नीचे बनाता है धीमा के लिए जाना जाता है। यदि आपको हेडर फ़ाइल में उनकी आवश्यकता है, तो <iosfwd>इसके बजाय #including का प्रयास करें <iostream>और <iostream>शीर्षलेख को केवल कार्यान्वयन फ़ाइल में रखें। <iosfwd>हैडर आगे घोषणाओं केवल रखती है। दुर्भाग्य से अन्य मानक हेडर में एक संबंधित घोषणा शीर्षक नहीं है।

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

गार्ड की शर्तें

हेडर फ़ाइलों को एकल अनुवाद इकाई में एक से अधिक बार शामिल होने से बचाने के लिए गार्ड शर्तों का उपयोग करें।

#pragma once
#ifndef filename_h
#define filename_h

// Header declarations / definitions

#endif

प्राग्म और इफंड दोनों का उपयोग करके, आपको सादे मैक्रो समाधान की पोर्टेबिलिटी मिलती है, साथ ही संकलन गति अनुकूलन जो कुछ संकलक pragma onceनिर्देश की उपस्थिति में कर सकते हैं ।

अन्योन्याश्रयता को कम करना

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

संकलक विकल्प

पहले से तैयार हेडर

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

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

ccache एक और उपयोगिता है जो चीजों को गति देने के लिए कैशिंग तकनीकों का लाभ उठाती है।

समानांतरवाद का उपयोग करें

एक साथ संकलन करने के लिए कई कोर / सीपीयू का उपयोग करते हुए कई कंपाइलर / आईडीई समर्थन करते हैं। में जीएनयू मेक (आमतौर पर जीसीसी के साथ इस्तेमाल किया), का उपयोग -j [N]विकल्प। विजुअल स्टूडियो में, समानांतर में कई प्रोजेक्ट बनाने की अनुमति देने के लिए वरीयताओं के तहत एक विकल्प है। आप केवल प्रोजेक्ट-लेवल पैरालिज्म के बजाय फाइल-लेवल पैरालिज्म के /MPविकल्प का उपयोग कर सकते हैं ।

अन्य समानांतर उपयोगिताओं:

एक निम्न अनुकूलन स्तर का उपयोग करें

कंपाइलर जितना अधिक ऑप्टिमाइज़ करने की कोशिश करता है, उतना ही कठिन काम करना पड़ता है।

साझा पुस्तकालय

पुस्तकालयों में अपने कम बार संशोधित कोड को स्थानांतरित करने से संकलन समय कम हो सकता है। साझा पुस्तकालयों ( .soया .dll) का उपयोग करके , आप लिंकिंग समय को भी कम कर सकते हैं।

एक तेज़ कंप्यूटर प्राप्त करें

अधिक रैम, तेज हार्ड ड्राइव (एसएसडी सहित), और अधिक सीपीयू / कोर सभी संकलन गति में अंतर करेंगे।


11
Precompiled हेडर हालांकि सही नहीं हैं। इनका उपयोग करने का एक साइड इफेक्ट यह है कि आपको आवश्यकता से अधिक फाइलें शामिल हो जाती हैं (क्योंकि हर संकलन इकाई एक ही पूर्व-निर्धारित हेडर का उपयोग करती है), जो आवश्यकता से अधिक बार पूर्ण recompiles को बाध्य कर सकती है। सिर्फ मन में रखने वाली कुछ बातें।
जल्फ

8
आधुनिक कंपाइलरों में, #ifndef एक बार में #pragma जितना ही तेज़ होता है (जब तक कि इसमें शामिल गार्ड फ़ाइल के शीर्ष पर होता है)। तो वहाँ एक बार के संकलन गति संदर्भ में #pragma को कोई लाभ नहीं है
jalf

7
यहां तक ​​कि अगर आपके पास सिर्फ वीएस 2005 है, 2008 नहीं है, तो आप .cpp स्तर पर समानांतर भवन को सक्षम करने के लिए संकलन विकल्पों में / एमपी स्विच जोड़ सकते हैं।
मैकबर्डी

6
यह उत्तर लिखे जाने पर SSD के प्रतिबंधात्मक रूप से महंगे थे, लेकिन आज वे C ++ का संकलन करते समय सबसे अच्छे विकल्प हैं। संकलित करते समय आप बहुत सी छोटी फ़ाइलों तक पहुँचते हैं;) इसके लिए बहुत सारे IOPS की जरूरत होती है, जो SSD का काम करता है।
एमएसएलटर्स 7

14
फ़ंक्शन हस्ताक्षरों में पास-दर-मूल्य के लिए पास-दर-संदर्भ देखें। यह हेडर फ़ाइल में संबंधित प्रकार की परिभाषाओं को #include करने की आवश्यकता को समाप्त कर देगा। यह गलत है , आपको फ़ंक्शन को घोषित करने के लिए पूर्ण प्रकार की आवश्यकता नहीं है जो मूल्य से गुजरता है, आपको केवल उस फ़ंक्शन को लागू करने या उपयोग करने के लिए पूर्ण प्रकार की आवश्यकता है , लेकिन ज्यादातर मामलों में (जब तक आप केवल कॉल अग्रेषित कर रहे हैं) आपको वैसे भी उस परिभाषा की आवश्यकता होगी।
डेविड रॉड्रिग्ज - ड्रिग्ज

43

मैं एसटीएपीएल परियोजना पर काम करता हूं जो कि भारी-भरकम सी ++ लाइब्रेरी है। एक बार थोड़ी देर में, हमें संकलन समय को कम करने के लिए सभी तकनीकों को फिर से देखना होगा। यहाँ, मैंने उन तकनीकों का सार प्रस्तुत किया है जिनका हम उपयोग करते हैं। इन तकनीकों में से कुछ पहले से ही ऊपर सूचीबद्ध हैं:

सबसे अधिक समय लेने वाले वर्गों का पता लगाना

हालाँकि, प्रतीक की लंबाई और संकलन समय के बीच कोई सिद्ध संबंध नहीं है, हमने देखा है कि छोटे औसत प्रतीक आकार सभी संकलनकर्ताओं पर संकलन समय में सुधार कर सकते हैं। तो आपका पहला लक्ष्य यह है कि आप अपने कोड में सबसे बड़े प्रतीकों को खोजें।

विधि 1 - आकार के आधार पर प्रतीकों को क्रमबद्ध करें

आप nmउनके आकार के आधार पर प्रतीकों को सूचीबद्ध करने के लिए कमांड का उपयोग कर सकते हैं:

nm --print-size --size-sort --radix=d YOUR_BINARY

इस कमांड में --radix=d आप दशमलव संख्या में आकार देख सकते हैं (डिफ़ॉल्ट हेक्स है)। अब सबसे बड़े प्रतीक को देखकर, पहचानें कि क्या आप संबंधित वर्ग को तोड़ सकते हैं और इसे गैर-टेम्प्लेटेड भागों को आधार वर्ग में विभाजित करके, या कक्षा को कई वर्गों में विभाजित करके इसे फिर से डिज़ाइन करने का प्रयास कर सकते हैं।

विधि 2 - लंबाई के आधार पर प्रतीकों को क्रमबद्ध करें

आप नियमित nmकमांड को चला सकते हैं और अपनी पसंदीदा स्क्रिप्ट ( AWK , पायथन , आदि) को पाइप को उनकी लंबाई के आधार पर सॉर्ट करने के लिए पाइप कर सकते हैं । हमारे अनुभव के आधार पर, यह विधि उम्मीदवारों को पद्धति 1 से बेहतर बनाने में सबसे बड़ी परेशानी की पहचान करती है।

विधि 3 - टेंपलेट का उपयोग करें

" Templight एक है बजना आधारित समय और टेम्पलेट instantiations की स्मृति की खपत प्रोफ़ाइल और टेम्पलेट इन्स्टेन्शियशन प्रक्रिया में आत्मनिरीक्षण हासिल करने के लिए इंटरैक्टिव डिबगिंग सत्र प्रदर्शन करने के लिए उपकरण"।

आप बाहर की जाँच करके Templight स्थापित कर सकते हैं LLVM और ( निर्देशों ) की और उस पर Templight पैच लागू । एलएलवीएम और क्लैंग के लिए डिफ़ॉल्ट सेटिंग डिबग और अभिकथन पर है, और ये आपके संकलन समय को महत्वपूर्ण रूप से प्रभावित कर सकते हैं। ऐसा लगता है जैसे टेंपलाइट को दोनों की आवश्यकता है, इसलिए आपको डिफ़ॉल्ट सेटिंग्स का उपयोग करना होगा। एलएलवीएम और क्लैंग को स्थापित करने की प्रक्रिया में लगभग एक घंटे का समय लगना चाहिए।

पैच को लागू करने के बाद आप templight++अपने कोड को संकलित करने के लिए स्थापना पर निर्दिष्ट बिल्ड फ़ोल्डर में स्थित का उपयोग कर सकते हैं ।

सुनिश्चित करें कि templight++आपके पेट में है। अब निम्नलिखित स्विच को अपने संकलन में संकलित करेंCXXFLAGS अपने मेकफाइल में या अपने कमांड लाइन विकल्प करें:

CXXFLAGS+=-Xtemplight -profiler -Xtemplight -memory -Xtemplight -ignore-system

या

templight++ -Xtemplight -profiler -Xtemplight -memory -Xtemplight -ignore-system

संकलन हो जाने के बाद, आपके पास .trace.memory.pbf और .trace.pbf एक ही फ़ोल्डर में उत्पन्न होंगे। इन निशानों की कल्पना करने के लिए, आप टेम्प्लाईट टूल्स का उपयोग कर सकते हैं जो इन्हें अन्य प्रारूपों में बदल सकते हैं। इन निर्देशों का पालन करेंTemplight-Convert स्थापित करने के लिए । हम आमतौर पर callgrind आउटपुट का उपयोग करते हैं। यदि आपका प्रोजेक्ट छोटा है तो आप ग्राफविज़ आउटपुट का भी उपयोग कर सकते हैं:

$ templight-convert --format callgrind YOUR_BINARY --output YOUR_BINARY.trace

$ templight-convert --format graphviz YOUR_BINARY --output YOUR_BINARY.dot

उत्पन्न कॉलग्रिंड फ़ाइल का उपयोग करके खोला जा सकता है kcachegrind जिसमें आप सबसे अधिक समय / स्मृति लेने वाली इन्स्टेन्शियशन ट्रेस कर सकते हैं।

टेम्प्लेट इंस्टेंटिएशन की संख्या कम करना

हालाँकि टेम्पलेट तात्कालिकता की संख्या को कम करने के लिए कोई सटीक समाधान नहीं है, फिर भी कुछ दिशानिर्देश हैं जो मदद कर सकते हैं:

एक से अधिक टेम्पलेट तर्कों के साथ रिफैक्टर वर्ग

उदाहरण के लिए, यदि आपके पास एक वर्ग है,

template <typename T, typename U>
struct foo { };

और दोनों का T और U10 अलग अलग विकल्प हैं कर सकते हैं, तो आप इस वर्ग के संभावित टेम्पलेट instantiations 100 एक तरह से करने के लिए इस सार के लिए एक अलग वर्ग के लिए कोड के आम हिस्सा है हल करने के लिए बढ़ा दी है। दूसरी विधि वंशानुक्रम व्युत्क्रम (वर्ग पदानुक्रम को उलट) का उपयोग करना है, लेकिन यह सुनिश्चित करें कि इस तकनीक का उपयोग करने से पहले आपके डिजाइन लक्ष्यों से समझौता नहीं किया जाता है।

व्यक्तिगत अनुवाद इकाइयों के लिए रिफलेक्टर नॉन-टेम्पलेटेड कोड

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

बाहरी टेम्प्लेट इंस्टेंटिएशन का उपयोग करें (C ++ 11 के बाद से)

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

उदाहरण के लिए:

enum class PossibleChoices = {Option1, Option2, Option3}

template <PossibleChoices pc>
struct foo { };

हम जानते हैं कि इस वर्ग में तीन संभावित तात्कालिकताएँ हो सकती हैं:

template class foo<PossibleChoices::Option1>;
template class foo<PossibleChoices::Option2>;
template class foo<PossibleChoices::Option3>;

ऊपर एक अनुवाद इकाई में रखें और अपनी हेडर फ़ाइल में कक्षा की परिभाषा के नीचे बाहरी कीवर्ड का उपयोग करें:

extern template class foo<PossibleChoices::Option1>;
extern template class foo<PossibleChoices::Option2>;
extern template class foo<PossibleChoices::Option3>;

यह तकनीक आपको समय की बचत कर सकती है यदि आप विभिन्न परीक्षणों को एक सामान्य सेट के साथ संकलित कर रहे हैं।

नोट: MPICH2 इस बिंदु पर स्पष्ट तात्कालिकता की उपेक्षा करता है और हमेशा सभी संकलन इकाइयों में तात्कालिक कक्षाओं को संकलित करता है।

एकता बिल्ड का उपयोग करें

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

उदाहरण के लिए, मान लें कि आप तीन फ़ाइलें जाने foo1.cc, foo2.cc, foo3.ccऔर वे सभी शामिल हैं tupleसे एसटीएल । आप ऐसा बना सकते हैं foo-all.ccजो दिखता है:

#include "foo1.cc"
#include "foo2.cc"
#include "foo3.cc"

आप इस फ़ाइल को केवल एक बार संकलित करते हैं और संभावित रूप से तीन फ़ाइलों के बीच सामान्य तात्कालिकता को कम करते हैं। आम तौर पर यह अनुमान लगाना कठिन है कि सुधार महत्वपूर्ण हो सकता है या नहीं। लेकिन एक स्पष्ट तथ्य यह है कि आप अपने बिल्ड में समानता खो देंगे (आप एक ही समय में तीन फ़ाइलों को संकलित नहीं कर सकते हैं)।

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

पूर्वनिर्धारित हेडर

Precompiled हेडर (PCH) संकलक द्वारा पहचाने जाने वाले मध्यवर्ती प्रतिनिधित्व के लिए आपकी हेडर फ़ाइलों को संकलित करके संकलन में बहुत समय बचा सकते हैं। पहले से तैयार हेडर फ़ाइलों को बनाने के लिए, आपको केवल अपनी हेडर फ़ाइल को अपने नियमित संकलन कमांड के साथ संकलित करना होगा। उदाहरण के लिए, जीसीसी पर:

$ g++ YOUR_HEADER.hpp

यह उत्पन्न होगा एक YOUR_HEADER.hpp.gch file( .gchएक ही फ़ोल्डर में जीसीसी में PCH फ़ाइलों के लिए विस्तार है)। इसका मतलब यह है कि यदि आप YOUR_HEADER.hppकिसी अन्य फ़ाइल में शामिल करते हैं , तो कंपाइलर आपके YOUR_HEADER.hpp.gchबजाय YOUR_HEADER.hppपहले वाले फ़ोल्डर में उपयोग करेगा ।

इस तकनीक के साथ दो मुद्दे हैं:

  1. आपको यह सुनिश्चित करना होगा कि पूर्वनिर्धारित की जा रही हेडर फाइलें स्थिर हैं और बदलने वाली नहीं हैं ( आप हमेशा अपना मेकफाइल बदल सकते हैं )
  2. आप केवल एक पीसीएच प्रति संकलन इकाई (अधिकांश संकलक पर) शामिल कर सकते हैं। इसका मतलब है कि यदि आपके पास एक से अधिक हेडर फ़ाइल प्री-कंपाइल की जानी हैं, तो आपको उन्हें एक फ़ाइल (जैसे all-my-headers.hpp) में शामिल करना होगा। लेकिन इसका मतलब है कि आपको नई फाइल को सभी जगहों पर शामिल करना होगा। सौभाग्य से, जीसीसी के पास इस समस्या का समाधान है। इसका उपयोग करें -includeऔर इसे नई हेडर फ़ाइल दें। आप इस तकनीक का उपयोग करके अलग-अलग फ़ाइलों को कॉमा कर सकते हैं।

उदाहरण के लिए:

g++ foo.cc -include all-my-headers.hpp

अनाम या अनाम नामस्थान का उपयोग करें

अनाम स्थान (उर्फ अनाम नामस्थान) उत्पन्न बाइनरी आकार को काफी कम कर सकते हैं। हेज़स्पेस आंतरिक लिंकेज का उपयोग करते हैं, जिसका अर्थ है कि उन नामस्थानों में उत्पन्न प्रतीक अन्य टीयू (अनुवाद या संकलन इकाइयों) को दिखाई नहीं देंगे। कंपाइलर आमतौर पर अनाम नामस्थान के लिए अद्वितीय नाम उत्पन्न करते हैं। इसका मतलब है कि अगर आपके पास कोई फ़ाइल foo.hpp है:

namespace {

template <typename T>
struct foo { };
} // Anonymous namespace
using A = foo<int>;

और आप इस फाइल को दो TUs (दो .cc फ़ाइलों में शामिल करें और उन्हें अलग-अलग संकलित करें) में शामिल करें। दो फू टेम्पलेट उदाहरण समान नहीं होंगे। यह वन डेफिनिशन रूल (ODR) का उल्लंघन करता है । उसी कारण से, अनाम नामस्थान का उपयोग करके हेडर फ़ाइलों में हतोत्साहित किया जाता है। .ccअपनी बाइनरी फ़ाइलों में दिखाए गए प्रतीकों से बचने के लिए अपनी फ़ाइलों में उनका उपयोग करने के लिए स्वतंत्र महसूस करें । कुछ मामलों में, .ccफ़ाइल के लिए सभी आंतरिक विवरणों को बदलने से उत्पन्न बाइनरी आकारों में 10% की कमी देखी गई।

दृश्यता विकल्प बदलना

नए संकलक में आप अपने प्रतीकों को डायनामिक शेयर्ड ऑब्जेक्ट्स (DSO) में दृश्यमान या अदृश्य होने के लिए चुन सकते हैं। आदर्श रूप से, दृश्यता बदलने से कंपाइलर प्रदर्शन, लिंक टाइम ऑप्टिमाइज़ेशन (LTO), और उत्पन्न बाइनरी आकार में सुधार हो सकता है। यदि आप GCC में STL हैडर फ़ाइलों को देखते हैं तो आप देख सकते हैं कि इसका व्यापक रूप से उपयोग किया जाता है। दृश्यता विकल्पों को सक्षम करने के लिए, आपको अपना कोड प्रति फ़ंक्शन, प्रति वर्ग, प्रति चर और अधिक महत्वपूर्ण रूप से प्रति संकलक में बदलना होगा।

दृश्यता की सहायता से आप उन प्रतीकों को छिपा सकते हैं जिन्हें आप उन्हें उत्पन्न साझा वस्तुओं से निजी मानते हैं। जीसीसी पर आप डिफ़ॉल्ट रूप से या -visibilityअपने कंपाइलर के विकल्प को छिपाकर प्रतीकों की दृश्यता को नियंत्रित कर सकते हैं । यह कुछ अर्थों में अनाम नामस्थान के समान है, लेकिन अधिक विस्तृत और घुसपैठ तरीके से।

यदि आप प्रति मामले में विज़ुअलाइज़ेशन निर्दिष्ट करना चाहते हैं, तो आपको अपने कार्यों, चर, और कक्षाओं में निम्नलिखित विशेषताएं जोड़ना होंगी:

__attribute__((visibility("default"))) void  foo1() { }
__attribute__((visibility("hidden")))  void  foo2() { }
__attribute__((visibility("hidden")))  class foo3   { };
void foo4() { }

जीसीसी में डिफ़ॉल्ट दृश्यता डिफ़ॉल्ट (सार्वजनिक) है, जिसका अर्थ है कि यदि आप उपरोक्त को एक साझा पुस्तकालय ( -shared) विधि के रूप में संकलित करते हैं , foo2और foo3अन्य टीयूएस ( foo1और दृश्यमान होगा ) में कक्षा दिखाई नहीं foo4देगी। यदि आप संकलित करते हैं -visibility=hiddenतो केवल foo1दिखाई देगा। foo4छुप भी जाता होगा।

आप जीसीसी विकी पर दृश्यता के बारे में अधिक पढ़ सकते हैं ।


33

मैं इन लेखों को "खेल से भीतर, इंडी खेल डिजाइन और प्रोग्रामिंग" से सुझाऊंगा:

दी, वे बहुत पुराने हैं - आपको वास्तविक परिणाम प्राप्त करने के लिए नवीनतम संस्करणों (या आपके लिए उपलब्ध संस्करणों) के साथ सब कुछ फिर से परीक्षण करना होगा। किसी भी तरह से, यह विचारों के लिए एक अच्छा स्रोत है।


17

एक तकनीक जो अतीत में मेरे लिए बहुत अच्छी तरह से काम करती थी: स्वतंत्र रूप से कई सी ++ स्रोत फ़ाइलों को संकलित नहीं करती है, बल्कि एक सी ++ फाइल उत्पन्न करती है जिसमें अन्य सभी फाइलें शामिल हैं, जैसे:

// myproject_all.cpp
// Automatically generated file - don't edit this by hand!
#include "main.cpp"
#include "mainwindow.cpp"
#include "filterdialog.cpp"
#include "database.cpp"

बेशक इसका मतलब है कि आपको किसी भी स्रोत में बदलाव होने पर सभी शामिल स्रोत कोड को फिर से जोड़ना होगा, इसलिए निर्भरता का पेड़ खराब हो जाएगा। हालाँकि, कई स्रोत फ़ाइलों को एक अनुवाद इकाई के रूप में संकलित करना कम से कम ( MSVC और GCC के साथ मेरे प्रयोगों में ) है और छोटे बायनेरिज़ बनाता है। मुझे यह भी संदेह है कि संकलक को अनुकूलन के लिए अधिक संभावना दी जाती है (क्योंकि यह एक ही बार में अधिक कोड देख सकता है)।

यह तकनीक विभिन्न मामलों में टूट जाती है; उदाहरण के लिए, संकलक दो या दो से अधिक स्रोत फ़ाइलों को एक ही नाम के साथ वैश्विक फ़ंक्शन घोषित करने पर जमानत कर देगा। मैं किसी भी अन्य उत्तर में वर्णित इस तकनीक को नहीं ढूँढ सका, इसीलिए मैं यहाँ इसका उल्लेख कर रहा हूँ।

क्या यह लायक है, केडीई परियोजना ने 1999 के बाद से अनुकूलित बायनेरिज़ (संभवतः एक रिलीज़ के लिए) बनाने के लिए इस सटीक उसी तकनीक का उपयोग किया। बिल्ड कॉन्फ़िगर स्क्रिप्ट पर स्विच को कॉल किया गया था --enable-final। पुरातात्विक अभिरुचि में से मैंने उस पोस्टिंग को खोद दिया जिसमें इस सुविधा की घोषणा की गई थी: http://lists.kde.org/?l=kde-devel&m=92722836009368&w=2


2
मुझे यकीन नहीं है कि अगर यह वास्तव में एक ही बात है, लेकिन मुझे लगता है कि कुलपति ++ ( msdn.microsoft.com/en-us/library/0zza0de8%28VS.71%29.aspx ) में "संपूर्ण कार्यक्रम अनुकूलन" चालू करना चाहिए आप जो सुझाव दे रहे हैं, उसकी तुलना में रनटाइम प्रदर्शन पर एक ही प्रभाव। संकलन समय, हालांकि, निश्चित रूप से आपके दृष्टिकोण में बेहतर हो सकता है!
फिलिप

1
@ फ़्रीच: आप OJ के उत्तर में वर्णित एकता बिल्ड का वर्णन कर रहे हैं। मैंने उन्हें थोक बिल्ड और मास्टर बिल्ड भी कहा है।
idbrii

तो एक UB WPO / LTCG से तुलना कैसे करता है?
पौलएम २ pa

यह केवल एक बार के संकलन के लिए संभावित रूप से उपयोगी है, न कि विकास के दौरान जहां आप संपादन, भवन और परीक्षण के बीच चक्र करते हैं। आधुनिक दुनिया में चार कोर आदर्श है, शायद कुछ साल बाद कोर की गिनती काफी अधिक है। यदि कंपाइलर और लिंकर कई थ्रेड्स का उपयोग करने में सक्षम नहीं हैं, तो फ़ाइलों की सूची को संभवतः उन सब्लिस्ट्स को <core-count> + Nविभाजित किया जा सकता है जो समानांतर संकलित किए जाते हैं जहां Nकुछ उपयुक्त पूर्णांक (सिस्टम मेमोरी और मशीन का उपयोग कैसे किया जाता है) के आधार पर किया जाता है।
FooF

15

इस विषय पर एक पूरी पुस्तक है, जिसका शीर्षक लार्ज-स्केल C ++ सॉफ्टवेयर डिज़ाइन (जॉन लैकोस द्वारा लिखित) है।

पुस्तक प्री-डेट्स टेम्प्लेट है, इसलिए उस पुस्तक की सामग्री में "टेम्प्लेट का उपयोग करके भी, संकलनकर्ता को धीमा कर सकता है" जोड़ें।


इस प्रकार के विषयों में पुस्तक को अक्सर संदर्भित किया जाता है लेकिन मेरे लिए यह जानकारी में विरल था। यह मूल रूप से जितना संभव हो उतना आगे की घोषणाओं का उपयोग करने और निर्भरता को कम करने के लिए कहता है। यह थोड़ा स्पष्ट है कि इसके अलावा pimpl मुहावरे का उपयोग करके रनटाइम कमियां हैं।
Gast128

@ Gast128 मुझे लगता है कि इसका उपयोग कोडिंग मुहावरों का उपयोग करना है जो वृद्धिशील पुन: संकलन की अनुमति देता है, अर्थात, यदि आप थोड़ा सा स्रोत बदलते हैं तो आपको सब कुछ फिर से तैयार नहीं करना पड़ेगा।
क्रिस डब्ल्यूबी

15

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

एक अन्य विकल्प है, जब आप GNU मेक के साथ काम करते हैं, -j<N>विकल्प चालू करने के लिए:

  -j [N], --jobs[=N]          Allow N jobs at once; infinite jobs with no arg.

मैं आमतौर पर यह है 3क्योंकि मैं यहाँ एक दोहरी कोर मिल गया है। यह अलग-अलग अनुवाद इकाइयों के लिए समानांतर में संकलक चलाएगा, बशर्ते उनके बीच कोई निर्भरता न हो। लिंकिंग को समानांतर में नहीं किया जा सकता है, क्योंकि सभी ऑब्जेक्ट फ़ाइलों को एक साथ जोड़ने वाली केवल एक लिंकर प्रक्रिया है।

लेकिन लिंकर को स्वयं थ्रेड किया जा सकता है, और यह वही है जो ईएलएफ लिंकर करता है। यह अनुकूलित थ्रेडेड C ++ कोड है, जो कहा जाता है कि ELF ऑब्जेक्ट फाइल्स को पुराने की तुलना में तेज़ी से लिंक करता है (और वास्तव में इसे बन्सिल में शामिल किया गया था )।GNU gold ld


हाँ ठीक है। क्षमा करें कि जब मैंने खोज की तो यह प्रश्न सामने नहीं आया।
स्कॉट लैंगहम

आपको खेद नहीं होना चाहिए। यह दृश्य C ++ के लिए था। आपका प्रश्न किसी भी संकलक के लिए प्रतीत होता है। ताकि के ठीक :)
Johannes Schaub - litb

12

यहाँ कुछ हैं:

  • एकाधिक-संकलित कार्य प्रारंभ करके सभी प्रोसेसर कोर का उपयोग करें ( make -j2यह एक अच्छा उदाहरण है)।
  • बंद करें या कम अनुकूलन (उदाहरण के लिए, जीसीसी ज्यादा के साथ तेजी से होता है -O1की तुलना में -O2या -O3)।
  • पूर्वगामी हेडर का उपयोग करें ।

12
FYI करें, मुझे लगता है कि कोर की तुलना में अधिक प्रक्रियाएँ शुरू करना आम तौर पर तेज़ है। एक क्वाड कोर सिस्टम पर उदाहरण के लिए, मैं आमतौर पर -j8 का उपयोग करता हूं, न कि -j4 का। इसका कारण यह है कि जब एक प्रक्रिया I / O पर अवरुद्ध हो जाती है, तो दूसरा संकलन हो सकता है।
श्री फूज़

@MrFooz: मैंने कुछ साल पहले i7-2700k (4 कोर, 8 थ्रेड्स, मैंने एक निरंतर गुणक सेट किया) पर लिनक्स कर्नेल (रैम स्टोरेज से) का संकलन करके इसका परीक्षण किया था। मैं सटीक सबसे अच्छा परिणाम भूल जाते हैं, लेकिन -j12चारों ओर करने के लिए -j18काफी तेजी से थे -j8, तो आप सुझाव है बस के रूप में। मैं सोच रहा हूं कि मेमोरी बैंडविड्थ सीमित होने से पहले आपके पास कितने कोर हो सकते हैं ...
मार्क के कोवान

@ मर्ककॉवन यह बहुत सारे कारकों पर निर्भर करता है। अलग-अलग कंप्यूटरों में बेतहाशा अलग-अलग मेमोरी बैंडविंड हैं। इन दिनों उच्च अंत प्रोसेसर के साथ, यह मेमोरी बस को संतृप्त करने के लिए कई कोर लेता है। इसके अलावा, I / O और CPU के बीच संतुलन है। कुछ कोड को संकलित करना बहुत आसान है, अन्य कोड धीमा हो सकता है (जैसे बहुत सारे टेम्पलेट के साथ)। अंगूठे का मेरा वर्तमान नियम -j2x के साथ वास्तविक कोर की संख्या है।
श्री फूज

11

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

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

उत्तरार्द्ध, ccache, एक संकलक कैश है। यह फिर से प्रीप्रोसेसर को निष्पादित करता है और फिर एक आंतरिक डेटाबेस (स्थानीय निर्देशिका में आयोजित) के साथ जांच करता है कि क्या प्रीप्रोसेसर फ़ाइल पहले से ही समान कंपाइलर मापदंडों के साथ संकलित की गई है। यदि ऐसा होता है, तो यह कंपाइलर के पहले रन से बाइनरी और आउटपुट को पॉप अप करता है।

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


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

9

जब मैं कॉलेज से बाहर आया, तो पहला वास्तविक उत्पादन-योग्य C ++ कोड जो मैंने देखा था, उनमें ये आर्कन #ifndef ... #endif निर्देश थे, जिनके बीच हेडर परिभाषित थे। मैंने उस व्यक्ति से पूछा जो बहुत ही भोले अंदाज में इन ओवररचिंग चीजों के बारे में कोड लिख रहा था और बड़े पैमाने पर प्रोग्रामिंग की दुनिया में पेश किया गया था।

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


1
पुराना लेकिन सोने के जैसा खरा। कभी-कभी स्पष्ट भूल जाता है।
alcor

1
'गार्ड्स शामिल करें'
Gast128

8

अधिक रैम।

किसी अन्य उत्तर में रैम ड्राइव के बारे में किसी ने बात की। मैंने ऐसा 80286 और टर्बो सी ++ (उम्र दिखाता है) के साथ किया और परिणाम अभूतपूर्व थे। जैसा कि मशीन के दुर्घटनाग्रस्त होने पर डेटा का नुकसान हुआ था।


डॉस में आप बहुत याद नहीं कर सकते हैं
phuclv

6

आगे की घोषणाओं का उपयोग करें जहाँ आप कर सकते हैं। यदि कोई क्लास डिक्लेरेशन केवल एक पॉइंटर या रेफरेंस का उपयोग करता है, तो आप केवल इसे घोषित कर सकते हैं और कार्यान्वयन फ़ाइल में टाइप के लिए हेडर शामिल कर सकते हैं।

उदाहरण के लिए:

// T.h
class Class2; // Forward declaration

class T {
public:
    void doSomething(Class2 &c2);
private:
    Class2 *m_Class2Ptr;
};

// T.cpp
#include "Class2.h"
void Class2::doSomething(Class2 &c2) {
    // Whatever you want here
}

यदि आप इसे पर्याप्त रूप से करते हैं तो फ़्यूज़र में प्रीप्रोसेसर के लिए बहुत कम काम शामिल है।


क्या केवल यही बात नहीं है जब एक ही हेडर को कई अनुवाद इकाइयों में शामिल किया जाता है? यदि केवल एक अनुवाद इकाई है (जैसा कि अक्सर जब टेम्पलेट का उपयोग किया जाता है) तो यह कोई प्रभाव नहीं पड़ेगा।
हमेशा 15

1
यदि केवल एक अनुवाद इकाई है, तो इसे हेडर में डालने से परेशान क्यों हैं? स्रोत फ़ाइल में केवल सामग्री डालने के लिए यह अधिक समझ में नहीं आएगा? हेडर की पूरी बात यह नहीं है कि यह एक से अधिक स्रोत फ़ाइल द्वारा शामिल किए जाने की संभावना है?
इवान टेरान


5

उपयोग

#pragma once

हेडर फ़ाइलों के शीर्ष पर, इसलिए यदि वे एक अनुवाद इकाई में एक से अधिक बार शामिल किए जाते हैं, तो हेडर का पाठ केवल शामिल हो जाएगा और एक बार पार्स हो जाएगा।


2
हालाँकि व्यापक रूप से समर्थित, #pragma एक बार गैर-मानक है। En.wikipedia.org/wiki/Pragma_once
ChrisInEdmonton

7
और इन दिनों, नियमित रूप से शामिल गार्डों का समान प्रभाव होता है। जब तक वे फ़ाइल के शीर्ष पर रहे हैं, संकलक एक बार #pragma के रूप में उन्हें इलाज के लिए पूरी तरह से सक्षम है
jalf

5

पूर्णता के लिए: एक निर्माण धीमा हो सकता है क्योंकि निर्माण प्रणाली बेवकूफ होने के साथ-साथ क्योंकि संकलक को अपना काम करने में लंबा समय लग रहा है।

यूनिक्स वातावरण में इस विषय की चर्चा के लिए रिकर्सिव मेक को कंसीडरेड हार्मफुल (पीडीएफ) पढ़ें ।


4
  • अपना कंप्यूटर अपग्रेड करें

    1. एक क्वाड कोर (या एक दोहरी-क्वाड सिस्टम) प्राप्त करें
    2. राम के बहुत जाओ।
    3. फ़ाइल I / O विलंब को कम करने के लिए RAM ड्राइव का उपयोग करें। (ऐसी कंपनियां हैं जो आईडीई और एसएटीए रैम ड्राइव बनाती हैं जो हार्ड ड्राइव की तरह काम करती हैं)।
  • फिर आपके पास आपके सभी अन्य विशिष्ट सुझाव हैं

    1. यदि उपलब्ध हो तो पहले से तैयार हेडर का प्रयोग करें।
    2. अपनी परियोजना के कुछ हिस्सों के बीच युग्मन की मात्रा कम करें। एक हेडर फ़ाइल को बदलने के लिए आमतौर पर आपकी पूरी परियोजना को फिर से शुरू करने की आवश्यकता नहीं होती है।

4

मुझे रैम ड्राइव का उपयोग करने का विचार था । यह पता चला कि मेरी परियोजनाओं के लिए यह सब के बाद एक फर्क नहीं पड़ता है। लेकिन तब वे अभी भी बहुत छोटे हैं। कोशिश करो! मुझे यह सुनने में दिलचस्पी होगी कि इससे कितनी मदद मिली।


हुह। किसी ने इसे डाउन-वोट क्यों किया? मैं इसे कल की कोशिश कर रहा हूँ।
स्कॉट लैंगहम

1
मुझे उम्मीद है कि गिरावट का कारण यह है कि इससे कभी कोई फर्क नहीं पड़ता। यदि आपके पास पर्याप्त अप्रयुक्त रैम है, तो ओएस बुद्धिमानी से इसे डिस्क कैश के रूप में वैसे भी उपयोग करेगा।
MSALERS

1
@MSalters - और "पर्याप्त" कितना होगा? मुझे पता है कि कि सिद्धांत है, लेकिन कुछ एक RAMdrive का उपयोग कर कारण के लिए करता है वास्तव में एक महत्वपूर्ण बढ़ावा देने के। गो फिगर ...
विल्क्स-

1
अपने प्रोजेक्ट को संकलित करने के लिए पर्याप्त है और फिर भी इनपुट और अस्थायी फ़ाइलों को कैश करें। जाहिर है जीबी में पक्ष सीधे आपके परियोजना के आकार पर निर्भर करेगा। यह ध्यान दिया जाना चाहिए कि पुराने OS'es (विशेष रूप से WinXP) पर फ़ाइल कैश काफी आलसी थे, रैम को अप्रयुक्त छोड़कर।
MSALERS

निश्चित रूप से राम ड्राइव तेज है अगर फ़ाइलें पहले से ही राम में हैं, बजाय धीमी गति के IO का एक पूरा गुच्छा, तो वे राम में हैं? (उन फ़ाइलों के लिए वृद्धि-दोहराएं जो बदल गई हैं - उन्हें डिस्क आदि पर वापस लिखें)।
पौलम्

3

डायनेमिक लिंकिंग (.so) स्टैटिक लिंकिंग (.a) की तुलना में बहुत तेज हो सकती है। खासकर जब आपके पास धीमी नेटवर्क ड्राइव हो। यह तब से है क्योंकि आपके पास .a फ़ाइल में सभी कोड हैं जिन्हें संसाधित करने और लिखने की आवश्यकता है। इसके अलावा, एक बहुत बड़ी निष्पादन योग्य फ़ाइल को डिस्क पर लिखा जाना चाहिए।


डायनेमिक लिंकिंग कई तरह के लिंक-टाइम ऑप्टिमाइजेशन को रोकती है, ताकि आउटपुट कई मामलों में धीमा हो जाए
phuclv

3

संकलन समय के बारे में नहीं, लेकिन निर्माण समय के बारे में:

  • का प्रयोग करें ccache आप एक ही फाइल को फिर से बनाने के लिए है, तो जब आप अपने buildfiles पर काम कर रहे

  • बनाने के बजाय निंजा-बिल्ड का उपयोग करें । मैं वर्तमान में ~ 100 स्रोत फ़ाइलों के साथ एक परियोजना का संकलन कर रहा हूं और सब कुछ ccache द्वारा कैश किया गया है। 5 मिनट की जरूरत है, निंजा 1 से कम है।

आप अपने निंजा फाइलों को cmake से जनरेट कर सकते हैं -GNinja


3

आप अपना समय कहाँ बिता रहे हैं? क्या आप सीपीयू से बंधे हैं? मेमोरी बाउंड? डिस्क बाध्य है? क्या आप अधिक कोर का उपयोग कर सकते हैं? अधिक रैम? क्या आपको RAID की आवश्यकता है? क्या आप बस अपने वर्तमान सिस्टम की दक्षता में सुधार करना चाहते हैं?

Gcc / g ++ के तहत, क्या आपने ccache को देखा है ? यदि आप make clean; makeबहुत कुछ कर रहे हैं तो यह मददगार हो सकता है ।


2

तेज़ हार्ड डिस्क।

कंपाइलर डिस्क में कई (और संभवतः विशाल) फाइलें लिखते हैं। विशिष्ट हार्ड डिस्क के बजाय SSD के साथ काम करना और संकलन समय बहुत कम है।



2

जैसे-जैसे विलंब होता है, वैसे-वैसे नेटवर्क शेयर आपके निर्माण में भारी कमी करेंगे। बूस्ट जैसी किसी चीज़ के लिए, मेरे लिए यह बहुत बड़ा अंतर था, भले ही हमारी नेटवर्क शेयर ड्राइव बहुत तेज़ हो। एक खिलौना बूस्ट प्रोग्राम को संकलित करने का समय लगभग 1 मिनट से 1 सेकंड तक रहा जब मैंने एक नेटवर्क शेयर से एक स्थानीय एसएसडी में स्विच किया।


2

यदि आपके पास मल्टीकोर प्रोसेसर है, तो विजुअल स्टूडियो (2005 और बाद) दोनों के साथ-साथ जीसीसी मल्टी प्रोसेसर प्रोसेसर का समर्थन करता है। यह सुनिश्चित करने के लिए कि आपके पास हार्डवेयर है, यह सुनिश्चित करने के लिए कुछ है।


2
@ फ़ेलमैन, कुछ अन्य उत्तर देखें - -j # विकल्प का उपयोग करें।
स्ट्रैजर

1

हालांकि एक "तकनीक" नहीं है, मैं यह पता नहीं लगा सका कि Win32 प्रोजेक्ट्स कई स्रोत फ़ाइलों के साथ मेरे "हैलो वर्ल्ड" खाली प्रोजेक्ट की तुलना में तेजी से संकलित हैं। इस प्रकार, मुझे आशा है कि इससे किसी को मदद मिलेगी जैसे उसने मुझे किया।

विजुअल स्टूडियो में, संकलन समय बढ़ाने का एक विकल्प इंक्रीमेंटल लिंकिंग ( / INCREMENTAL ) है। यह लिंक-टाइम कोड जनरेशन ( / LTCG ) के साथ असंगत है इसलिए रिलीज बिल्ड बनाते समय वृद्धिशील लिंकिंग को अक्षम करना याद रखें।


1
लिंक-टाइम कोड जनरेट करना अक्षम करना एक अच्छा सुझाव नहीं है क्योंकि यह कई अनुकूलन अक्षम करता है। आपको /INCREMENTALडीबग मोड में सक्षम करने की आवश्यकता है
phuclv

1

विजुअल स्टूडियो 2017 से शुरू होने में समय लगता है।

उन गुणों को प्रोजेक्ट गुण विंडो में C / C ++ -> कमांड लाइन (अतिरिक्त विकल्प) में जोड़ें: /Bt+ /d2cgsummary /d1reportTime

आप इस पोस्ट में और सुझाव दे सकते हैं ।


0

स्थैतिक के बजाय डायनेमिक लिंकिंग का उपयोग करके आप तेजी से कंपाइलर बना सकते हैं जो महसूस कर सकते हैं।

यदि आप t Cmake का उपयोग करते हैं, तो संपत्ति को सक्रिय करें:

set(BUILD_SHARED_LIBS ON)

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

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