यह महसूस करना महत्वपूर्ण है कि संकलक का उत्पादन करने वाले कोड को आपके डेटा संरचनाओं का कोई वास्तविक ज्ञान नहीं है (क्योंकि विधानसभा स्तर पर ऐसा कुछ मौजूद नहीं है), और न ही अनुकूलक। कंपाइलर प्रत्येक फ़ंक्शन के लिए केवल कोड का निर्माण करता है , न कि डेटा संरचनाओं का ।
ठीक है, यह भी निरंतर डेटा अनुभाग और ऐसे लिखता है।
उसके आधार पर, हम पहले ही कह सकते हैं कि ऑप्टिमाइज़र सदस्यों को "हटाएगा" या "समाप्त" नहीं करेगा, क्योंकि यह डेटा संरचनाओं को आउटपुट नहीं करता है। यह कोड आउटपुट करता है , जो सदस्यों का उपयोग नहीं कर सकता है या नहीं कर सकता है , और इसके लक्ष्यों के बीच सदस्यों के व्यर्थ उपयोग (यानी लिखते / पढ़ता है) को समाप्त करके मेमोरी या साइकिल को बचा रहा है ।
इसका सार यह है कि "यदि कंपाइलर किसी फंक्शन के दायरे में साबित हो सकता है (इन कार्यों को शामिल किया गया था) जिसमें अप्रयुक्त सदस्य इस बात से कोई फर्क नहीं पड़ता कि फंक्शन कैसे संचालित होता है (और यह क्या रिटर्न देता है) तो संभावनाएं अच्छी हैं कि सदस्य की उपस्थिति का कोई कारण नहीं है "।
जैसा कि आप बाहरी दुनिया के साथ एक फंक्शन की बातचीत को कंपाइलर के लिए अधिक जटिल / अस्पष्ट बनाते हैं (अधिक जटिल डेटा संरचनाओं को लेते / वापस करते हैं, उदाहरण के लिए std::vector<Foo>
, एक अलग संकलन इकाई में फ़ंक्शन की परिभाषा छिपाते हैं, inlid / dislcentivize inlid etc.) , यह अधिक से अधिक संभावना है कि संकलक साबित नहीं कर सकता है कि अप्रयुक्त सदस्य का कोई प्रभाव नहीं है।
यहां कोई कठिन नियम नहीं हैं क्योंकि यह सब कंपाइलर द्वारा किए गए अनुकूलन पर निर्भर करता है, लेकिन जब तक आप तुच्छ चीजें करते हैं (जैसे कि YSC के उत्तर में दिखाया गया है) यह बहुत संभावना है कि कोई ओवरहेड मौजूद नहीं होगा, जबकि जटिल चीजें करना (जैसे वापस लौटना) एक std::vector<Foo>
समारोह से (इनलाइनिंग के लिए बहुत बड़ा) शायद ओवरहेड को उकसाएगा।
बिंदु को समझने के लिए , इस उदाहरण पर विचार करें :
struct Foo {
int var1 = 3;
int var2 = 4;
int var3 = 5;
};
int test()
{
Foo foo;
std::array<char, sizeof(Foo)> arr;
std::memcpy(&arr, &foo, sizeof(Foo));
return arr[0] + arr[4];
}
हम यहां गैर-तुच्छ चीजें करते हैं (पते ले लो, निरीक्षण करें और बाइट प्रतिनिधित्व से बाइट्स जोड़ें ) और फिर भी आशावादी यह पता लगा सकता है कि इस प्लेटफॉर्म पर परिणाम हमेशा एक ही है:
test(): # @test()
mov eax, 7
ret
इतना ही Foo
नहीं किसी भी स्मृति पर कब्जा नहीं करने वाले सदस्य Foo
भी अस्तित्व में नहीं आए! यदि अन्य उपयोग हैं जो अनुकूलित नहीं किए जा सकते हैं तो उदाहरण के लिए sizeof(Foo)
यह महत्वपूर्ण हो सकता है - लेकिन केवल उस खंड के लिए! यदि सभी उपयोगों को इस तरह से अनुकूलित किया जा सकता है, तो उदा का अस्तित्व var3
उत्पन्न कोड को प्रभावित नहीं करता है। लेकिन अगर यह कहीं और उपयोग किया जाता है, test()
तो भी अनुकूलित रहेगा!
संक्षेप में: प्रत्येक उपयोग Foo
स्वतंत्र रूप से अनुकूलित है। कुछ एक अनावश्यक सदस्य के कारण अधिक मेमोरी का उपयोग कर सकते हैं, कुछ नहीं कर सकते हैं। अधिक जानकारी के लिए अपने संकलक मैनुअल से परामर्श करें।