2010-07-30 10 views
5

मुझे Visual C++ 9 प्रोग्राम में निम्न समस्या है। एक विशाल वस्तु है जिसमें तार्किक रूप से कई उप-तत्व होते हैं। मैं या तो ऑब्जेक्ट या स्टोर पॉइंटर्स के अंदर उपरोक्त को अलग-अलग आवंटित उप-प्रोजेक्ट में स्टोर कर सकता हूं।मेमोरी आवंटन के मामले में क्या बेहतर है - सबबोजेक्ट या एक पॉइंटर को एक अलग ऑब्जेक्ट में?

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

यहाँ कैसे मेरे विचार को विकसित करता है: यदि मैं उन्हें traversing थोड़ा तेज हो जाएगा अंदर subobjects स्टोर

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

इस बीच स्मृति विखंडन वास्तव में मुझे परेशान करता है - मुझे अपने कार्यक्रम को बहुत स्थिर और निरंतर महीनों से चलाने में सक्षम होना चाहिए।

मैं अपना निर्णय कैसे ले सकता हूं? क्या यह निर्णय लेने के लिए कोई तरीका है कि मुझे उपरोक्त विचारों के अनुसार छोटी वस्तु या बड़ी वस्तुओं का चयन करना चाहिए या नहीं?

उत्तर

2

कुछ बड़ी वस्तुओं को आवंटित करने से छोटी वस्तुओं की बड़ी संख्या आवंटित करने से कम स्मृति की कमी होगी। इससे भी महत्वपूर्ण बात यह है कि, आपकी ऑब्जेक्ट्स का एक बड़ा प्रतिशत बिल्कुल वही आकार है, इसलिए आप अक्सर एक मुक्त ब्लॉक का पुन: उपयोग करने में सक्षम होंगे। अपनी ऑब्जेक्ट को बड़ी संख्या में छोटी वस्तुओं में विभाजित करने से आमतौर पर विखंडन अधिक समस्या हो सकती है, कम नहीं।

यदि आपको लगता है कि विखंडन कोई समस्या बन जाती है, तो आप आमतौर पर अपने स्वयं के आवंटक को परिभाषित करके उस से निपटना चाहते हैं।

1

मैं कहूंगा कि आपको कई छोटे लोगों की बजाय एक बड़ी वस्तु को संग्रहित करके कम स्मृति विखंडन प्राप्त होगा। इस तरह से इसके बारे में सोचो। यदि आपके पास 100 एमबी मेमोरी है और आप 1 50 एमबी ऑब्जेक्ट आवंटित करते हैं तो सबसे खराब मामले में आपके पास दो 25 एमबी ब्लॉक उपलब्ध होंगे।

यदि आप दो 25 एमबी ब्लॉक आवंटित करते हैं तो सबसे खराब मामले में आपके पास 3 16 एमबी ब्लॉक हो सकते हैं। यह कम से कम विखंडन है।

0

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

साधारण तथ्य यह है कि subobjects साथ रचना हर संभव संबंध में सबसे तेज और सबसे छोटी विकल्प है। यदि आप ऐसा कर सकते हैं, तो करें।

यह भी इस तरह के स्वत: निर्माता/असाइनमेंट ऑपरेटर पीढ़ियों के रूप में कई रखरखाव से संबंधित तेजी, है।

0

आप स्मार्ट सूचक का उपयोग कर रहे हैं, तो आप अपने वस्तुओं को नष्ट कर दिया के बारे में कोई चिंता की जरूरत नहीं है, तो कोड मोटे तौर पर (स्मृति और प्रदर्शन में मामूली भूमि के ऊपर को छोड़ कर) एकत्रित वस्तु का उपयोग करने से बराबर। हालांकि समय के साथ अनुभव विनिर्देश परिवर्तन से, (आप बाद में वस्तुओं के बीच subobjects स्वैप करने के लिए की आवश्यकता होगी हो सकता है) यह subobject से सूचक का उपयोग करने के अधिक सुविधाजनक है। और बदतर मामले में (यदि आपके पास स्मृति या प्रदर्शन है) और सबबोजेक्ट वापस जाना चाहते हैं, तो आप आसानी से एक उपनिवेश बना सकते हैं और पुराना पॉइंटर पॉइंट कर सकते हैं, इसलिए आप कन्स्ट्रक्टर को छोड़कर कोड के किसी भी बिट को नहीं बदलना चाहते हैं, जैसे कि (छद्म कोड में) (आप भी एक #ifdef उपयोग कर सकते हैं आप इसे बदल सकते जब भी आप यदि आवश्यक हो तो एक कुछ मानक करना चाहते हैं)

class A 
{ 
#ifdef SUBOBJECT 
    B __b; 
#endif 
    B *b; 
    A() 
    { 
#ifdef SUBOBJECT 
    *b = &__b; 
#else 
    *b = new B(); 
#endif  
    }; 

    void f() 
    { 
    b->f(); 
    } 
} 
1

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

यदि उप-ऑब्जेक्ट्स उस ऑब्जेक्ट के सार्वजनिक इंटरफ़ेस में कोई भी भाग नहीं चलाते हैं तो आप उन्हें पिंपल कर सकते हैं, इस प्रकार बाहरी ऑब्जेक्ट के सार्वजनिक रूप से दिखाई देने वाले इंटरफ़ेस को कम कर सकते हैं और संभावित रूप से संकलित समय भी कम कर सकते हैं। फिर आप किसी सार्वजनिक दृश्यता के साथ कार्यान्वयन में छिपी हुई उप-वस्तुओं के कार्यान्वयन को निजी रूप से परिभाषित कर सकते हैं।

वैकल्पिक रूप से यदि स्वत: प्रबंधन की सुविधा से अपने डिजाइन लाभ करता है, तो सीधे निहित वस्तुओं है कि दृष्टिकोण का उपयोग करें।

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

0

जैसा कि अन्य ने यहां उल्लेख किया है, आपकी धारणा है कि कम आवंटन की तुलना में विखंडन के लिए कई छोटे आवंटन बेहतर हैं।

तो विखंडन एक बड़ी चिंता, सबसे अच्छा उपकरण है कि आप उपयोग कर सकते हैं स्मृति जमा है में से एक है। आप इस सवाल में कहते हैं कि "सबोबजेक्ट हमेशा एक ही आकार का होता है।" यदि यह सत्य है, तो आपके आवंटन और ढेर विखंडन को कम करने के लिए आपके लिए एक बड़ा अवसर है। बस अपनी खुद की आवंटन वस्तु बनाएं जो sizeof(SubObject) की स्मृति के ब्लॉक को हाथ से बाहर रखे। आपका बाहरी ऑब्जेक्ट पॉइंटर को उप-प्रोजेक्ट में संग्रहीत करेगा, जिसे आपके आवंटक के साथ आवंटित किया गया था। जब यह रद्द करना चाहता है, तो यह स्मृति को आवंटक ऑब्जेक्ट पर वापस रखता है। delete पर कॉल करने के बजाए आवंटक ऑब्जेक्ट, मेमोरी ब्लॉक को सहेज लेगा और अगली बार इसे आवंटन के लिए कहा जाएगा। आवंटक वस्तु ऐसे ब्लॉक की एक सूची संग्रहित करेगी और उन्हें रीसायकल करेगा। यह आपके द्वारा भारी मात्रा में ढेर आवंटन की संख्या को कम करेगा।

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