क्या हेडर-ओनली लाइब्रेरी अधिक कुशल हैं?


48

मान्यताओं

  1. C ++ के हेडर-ओनली लाइब्रेरी के फायदों में से एक यह है कि उन्हें अलग से संकलित करने की आवश्यकता नहीं है।

  2. C और C ++ में inlineकेवल तभी समझ में आता है जब फ़ंक्शन को हेडर फ़ाइल में परिभाषित किया गया है *।

  3. परंपरागत रूप से, C में .c / .h लेआउट का उपयोग किया गया है, जहां हेडर अनुवाद इकाई के न्यूनतम सार्वजनिक इंटरफ़ेस का प्रतिनिधित्व करता है। इसी तरह .cpp / hpp।

सवाल

क्या हेडर-ओनली लाइब्रेरियां आमतौर पर पारंपरिक लेआउट की तुलना में अधिक कुशल कोड- और निष्पादन समय वार होती हैं? यदि हां, तो क्या यह व्यापक इनलाइनिंग या अन्य अनुकूलन के कारण है?

* - एक हेडर में फ़ंक्शन को परिभाषित करना कंपाइलर को किसी भी अनुवाद इकाई के संकलन के दौरान कार्यान्वयन को देखने की अनुमति देता है और व्यावहारिक रूप से इनलाइनिंग कोड को संभव बनाता है।


2
आपको आश्चर्य होगा कि विभिन्न अनुवाद इकाइयों में आधुनिक C ++ लिंकर्स (GCC, MSVC, ICC, इत्यादि) कितनी अच्छी तरह से इनलाइन कोड कर सकते हैं। मैं कहूंगा कि आम तौर पर दक्षता के परिप्रेक्ष्य में "दी गई" संख्या को देखते हुए कई बार अनुकूलन करने वालों ने मेरी अपेक्षाओं को खारिज कर दिया और वैसे भी इनलाइन में कामयाब रहे (यह डायलिब संदर्भों को छोड़कर जहां हेडर में इनलाइनिंग या एक अलग सांख्यिकीय रूप से जुड़े पुस्तकालय में कार्यान्वयन प्रदान करने में मदद कर सकता है) । फिर भी हेडर-ओनली लाइब्रेरी, बशर्ते कि वे इंटरफ़ेस और कार्यान्वयन दोनों में स्थिर हों, क्योंकि वे आसानी से नई परियोजनाओं में तैनात किए जा सकते हैं।

1
मुझे नहीं पता कि यह एक पूर्ण उत्तर का हकदार है, लेकिन केवल कामेच्छा का एक बड़ा लाभ स्थापना और उपयोग में आसानी है: डाउनलोड, #include "lib.h (पीपी)", किया।
वीरेल

जवाबों:


44

C ++ के हेडर-ओनली लाइब्रेरी के फायदों में से एक यह है कि उन्हें अलग से संकलित करने की आवश्यकता नहीं है

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

C और C ++ इनलाइन केवल तभी समझ में आता है जब फ़ंक्शन को हेडर फ़ाइल में परिभाषित किया गया है *

यह संकलक / लिंकर प्रणाली पर निर्भर करता है, लेकिन मुझे लगता है कि अधिकांश मौजूदा सी और सी ++ संकलक के लिए यह सच है।

परंपरागत रूप से, C में .c / .h लेआउट का उपयोग किया गया है, जहां हेडर अनुवाद इकाई के न्यूनतम सार्वजनिक इंटरफ़ेस का प्रतिनिधित्व करता है। इसी तरह .cpp / hpp।

यह ज्यादातर सही है। C ++ क्लास हेडर में अक्सर न्यूनतम सार्वजनिक इंटरफ़ेस से अधिक होते हैं - वे आम तौर पर बहुत सारे निजी सामान होते हैं। इसे कम करने के लिए, PIMPL मुहावरे जैसी चीजों का उपयोग किया जाता है। यह हेडर-ओनली लाइब्रेरी के "विपरीत" जैसा कुछ है, यह आवश्यक हेडर सामग्री को कम से कम करने की कोशिश करता है।

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

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

IMHO हेडर-ओनली लिबास की लोकप्रियता टेम्प्लेट मेटा प्रोग्रामिंग की लोकप्रियता के कारण है। अधिकांश संकलक के लिए, टेम्पर्ड लिबास केवल हेडर होना चाहिए क्योंकि कंपाइलर केवल मुख्य कंपाइल प्रक्रिया शुरू कर सकता है जब टाइप पैरामीटर प्रदान किए जाते हैं, और पूर्ण संकलन और अनुकूलन के लिए कंपाइलर को "दोनों को एक बार" देखना होगा - लाइब्रेरी कोड प्लस टेम्पलेट पैरामीटर मान। यह असंभव है (या कम से कम कठिन) ऐसे पुस्तकालय के लिए किसी भी "precompiled" संकलन इकाइयों का उत्पादन करने के लिए।


6
इसलिए संक्षेप में, हेडर-ओनली लाइब्रेरी अधिक कुशल होने के बजाय अधिक सुविधाजनक हैं ; और चूंकि C ++ में कोई मानक पैकेज प्रबंधक नहीं है, इसलिए यह ड्राइविंग को अपनाने में मदद करता है।
मथिउ एम।

6
@ मैथ्यूएमएम: नहीं, संकलित कोड वास्तव में कभी-कभी अधिक कुशल हो सकता है, और टेम्पलेट लिबास के लिए हेडर-ओनली डिज़ाइन आमतौर पर सुविधा का सवाल नहीं है। और बढ़े हुए संकलित समय निश्चित रूप से अधिक सुविधाजनक नहीं हैं।
डॉक्टर ब्राउन

हेडर में हॉट कोड होने से वास्तव में अधिक कुशल संकलित कोड हो सकता है, हालांकि हेडर में सभी कोड होने की आवश्यकता नहीं है और हेडर-ओनली लाइब्रेरी से स्वतंत्र, IMHO है।
मैथ्यू एम।

1
@ मैथ्यूएमएम .: यह निश्चित रूप से सही है, फिर भी मुझे लगता है कि शब्द "अधिक सुविधाजनक" अच्छी तरह से मामले का वर्णन नहीं करता है।
डॉक्टर ब्राउन

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

15

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

  1. C ++ के हेडर-ओनली लाइब्रेरी के फायदों में से एक यह है कि उन्हें अलग से संकलित करने की आवश्यकता नहीं है।

अलग-अलग चीजों को संकलित करने का मतलब है कि संभवतः केवल एक भाग में परिवर्तन होने पर सब कुछ फिर से इकट्ठा न करना।
तो, एक लाभ के बजाय एक नुकसान।

  1. C और C ++ इनलाइन केवल तभी समझ में आता है जब फ़ंक्शन को हेडर फ़ाइल में परिभाषित किया गया है *।

हां, एकमात्र प्रभाव inlineबचा है जो एक-परिभाषा-नियम का अपवाद है ।
यद्यपि आप को पता है कि वे परिभाषाएँ किसी भी तरह से अलग हैं।

इसलिए, यदि कोई फ़ंक्शन किसी संकलन-इकाई में आंतरिक है, तो इसे चिह्नित करें static। इससे इनलाइनिंग की संभावना भी बढ़ जाती है, क्योंकि इसे इनलाइन करने के लिए फंक्शन की जरूरत होती है।
फिर भी, लिंक-टाइम-ऑप्टिमाइज़ेशन पर एक नज़र डालें, जैसा कि कम से कम MSVC ++, gcc और clang द्वारा समर्थित है।

  1. परंपरागत रूप से, C में .c / .h लेआउट का उपयोग किया गया है, जहां हेडर अनुवाद इकाई के न्यूनतम सार्वजनिक इंटरफ़ेस का प्रतिनिधित्व करता है। इसी तरह .cpp / hpp।

खैर, केवल न्यूनतम इंटरफ़ेस प्रस्तुत करना निश्चित रूप से लक्ष्यों में से एक है, उच्च एपीआई और एबीआई स्थिरता प्राप्त करने के लिए, और संकलन समय को कम करने के लिए।

विशेष रूप से C ++ क्लासेस वास्तव में इस बात के लिए तैयार नहीं हैं, कि जैसा कि सभी निजी बिट्स हेडर में लीक होते हैं, जैसा कि संरक्षित लोग करते हैं कि आप इसे प्राप्त करना चाहते हैं या नहीं।

डिज़ाइन-पैटर्न PIMPL ऐसे विवरणों को कम करने के लिए है।

वह भाग जहां इंटरफ़ेस को अलग करना और कार्यान्वयन पूरी तरह से C ++ में विफल रहता है, हालांकि टेम्प्लेट हैं।
समिति ने निर्यात किए गए टेम्पलेट्स के साथ कुछ करने की कोशिश की , लेकिन इसे बहुत जटिल माना गया है और वास्तव में काम नहीं कर रहा है।

अब, वे एक उचित मॉड्यूल सिस्टम पर काम कर रहे हैं , हालांकि यह धीमी गति से चल रहा है। यह गंभीर रूप से संकलन-समय को कम करता है, और इसकी सतह को कम करके एपीआई और एबीआई स्थिरता को भी बढ़ाना चाहिए।

क्या हेडर-ओनली लाइब्रेरियां आमतौर पर पारंपरिक लेआउट की तुलना में अधिक कुशल कोड- और निष्पादन समय वार होती हैं? यदि हां, तो क्या यह व्यापक इनलाइनिंग या अन्य अनुकूलन के कारण है?

हेडर-ओनली लाइब्रेरी कोड-आकार और निष्पादन-समय में अधिक कुशल हो सकते हैं, हालांकि यह इस बात पर निर्भर करता है कि लाइब्रेरी साझा की जाती है, इसका कितना उपयोग किया जाता है, किन तरीकों से किया जाता है, और क्या इनलाइनिंग उस विशिष्ट मामले में निर्णायक जीत साबित होती है।

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

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