2016-02-04 4 views
9

अगर मैं निम्नलिखित वर्ग है:कक्षा में सदस्यों का इष्टतम आदेश क्या है?

class Example 
{ 
    bool m_b1; 
    SomeClass m_sc; 
    bool m_b2; 
    char * m_name; 
    bool m_b3; 
    int m_i1; 
    SomeClass * m_sc; 
    int m_i2; 
}; 

सदस्यों के इष्टतम क्रम क्या है? जहां तक ​​मुझे पता है, सदस्यों की घोषणा का आदेश स्मृति के सदस्यों के क्रम के बराबर है, इस वर्ग का उदाहरण बनाते समय।

  • क्या मुझे सदस्यों को सॉर्ट करना चाहिए ताकि बराबर प्रकार एक साथ हो?
  • क्या सभी पॉइंटर्स एक ही प्रकार के रूप में गिना जाता है?
  • क्या पुनर्गठन वस्तु के आकार पर प्रभाव डालता है? क्या 4 या 8 बाइट संरेखण यहां लागू होता है?
  • मैं उपरोक्त के प्रभाव कैसे देख सकता हूं? क्या आकार ऑब्जेक्ट द्वारा उपयोग की गई स्मृति को संरेखण के लिए खाली स्थान समेत दिखाता है?
  • सदस्यों के क्रमबद्ध करने के लिए दिन के अंत में बेहतर है ताकि उनका अर्थ और संदर्भ समझना आसान हो?
+3

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

+0

मैं तर्क दूंगा कि ऑब्जेक्ट का ओवरलैल आकार रनटाइम पर अधिक प्रभाव डालता है जहां आप सदस्य घोषित किए जाते हैं। सभी सदस्यों को संकलन समय पर 'इस + ऑफ़सेट' की गणना करके सीपीयू द्वारा एक्साइज किया जाता है, इसलिए रनटाइम में कोई फर्क नहीं पड़ता –

उत्तर

6

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

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

+0

क्या आप जानते हैं कि "अधिक से अधिक" ऑर्डरिंग कहां से आती है? मेरा मानना ​​है कि आप विपरीत "छोटे से अधिक" ऑर्डरिंग के समान आकार प्राप्त करते हैं, साथ ही आपके पास एक छोटे से ऑफसेट पर अधिक सदस्य हैं। – davidhigh

+0

@ डेविडिघ मुझे नहीं पता कि ऑर्डरिंग कहां से आती है। मैंने कई स्थानों से सुना है (मेरे शिक्षकों में से एक, वेब पर कुछ सम्मेलन)। मुझे लगता है कि आप सही हैं, छोटे से अधिक एक ही आकार का उत्पादन करेंगे। "छोटा ऑफ़सेट" अप्रासंगिक है। अनुकूलन इस तथ्य से आता है कि ऑफसेट शून्य है (ऑफ़सेट कितना छोटा है)। एएलयू पर, '0' के साथ ऑपरेशन तेज़ हैं। मुझे लगता है कि '1' के साथ भी (उदाहरण के लिए वृद्धि)। इसके अलावा, ऑपरेंड कोई फर्क नहीं पड़ता (यदि यह '4',' 10' या '32' है)। – bolov

3

क्या मुझे सदस्यों को सॉर्ट करना चाहिए ताकि बराबर प्रकार एक साथ हो?

यदि यह पठनीयता बढ़ता है, हाँ!

क्या सभी पॉइंटर्स एक ही प्रकार के रूप में गिना जाता है?

हां, सभी पॉइंटर्स को 32 बिट या 64 बिट या जो कुछ भी सिस्टम परिभाषित करता है उसे लेना चाहिए।

क्या पुनर्गठन वस्तु के आकार पर प्रभाव डालता है? क्या 4 या 8 बाइट संरेखण यहां लागू होता है?

संरेखण के कारण यह संभव है। Live example

क्या सदस्यों को क्रमबद्ध करने के लिए दिन के अंत में बेहतर है ताकि उनके अर्थ और संदर्भ को समझना आसान हो?

यदि यह अर्थ, पठनीयता और रखरखाव बढ़ता है, हाँ।

8

क्रम महत्वपूर्ण है जब एक सदस्य चर जब प्रारंभकर्ता सूचियों का उपयोग कर किसी अन्य सदस्य चर पर निर्भर करता है:

दो चर जहां दूसरे चर (varC) के निर्माता की जरूरत पहले (varB)

के साथ एक कक्षा की कल्पना
class A 
{ 
    B varB; 
    C varC; 

    A() 
    : varC(varB) 
    { 
    } 
}; 

ऑर्डर तय करता है कि रचनाकारों को कौन से कदम निष्पादित किए जाते हैं, इसलिए varB और varC के क्रम को बदलने से varC को varC के एक प्रारंभिक ऑब्जेक्ट को पास किया जाएगा।

बेशक, शैली और पठनीयता भी महत्वपूर्ण है।

+0

कोड स्निपेट क्यों नहीं करता है, यह काम नहीं करता है। – Niall

+1

कोड स्निपेट के बावजूद, मुझे लगता है कि यह बिंदु बेहतर है। –

+0

क्षमा करें, मैंने गलत प्रकार का स्निपेट इस्तेमाल किया है, तो ऐसा लगता है :) –

1

मैंने जो अंगूठा सीखा है उसका एक अच्छा नियम "सबसे बड़ा चर पहले रखें"।

अपने उदाहरण में इस

class Example 
{ 

    SomeClass m_sc; 
    SomeClass * m_sc; 
    char * m_name; 
    int m_i1; 
    int m_i2; 
    bool m_b1; 
    bool m_b2; 
    bool m_b3; 
}; 

होगा मैं अपने विचारों को तैयार करने में सबसे अच्छा नहीं कर रहा हूँ, तो मेरे साथ सहन।

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

1

जवाब के अलावा उल्लेख से पहले:

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

एक बहुत अच्छा डेटा उन्मुख डिजाइन के बारे में लेख

यहां पाया जा सकता: Data-Oriented Design (Or Why You Might Be Shooting Yourself in The Foot With OOP)

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