2009-03-03 6 views
13

जब आपको बहुत छोटी वस्तुएं रखने की आवश्यकता होती है, तो कहें कि इसमें 2 फ्लोट संपत्ति है, और आपके पास लाखों लोग होंगे जो तुरंत "नष्ट" नहीं होंगे, क्या structs बेहतर विकल्प हैं या कक्षाएं?लंबी जीवित वस्तुओं के लिए संरचना बनाम वर्ग

लाइब्रेरी के रूप में xna की तरह, stru3s के रूप में बिंदु 3s हैं, लेकिन यदि आपको लंबे समय तक उन मानों को पकड़ने की आवश्यकता है, तो क्या यह प्रदर्शन खतरे को जन्म देगा?

उत्तर

33

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

कुछ युक्तियां:

:: struct 16 बाइट से बड़ी नहीं होना चाहिए, या आप प्रदर्शन लाभ खो देते हैं।

:: संरचना को अपरिवर्तनीय बनाएं। इससे उपयोग स्पष्ट हो जाता है।

उदाहरण:

public struct Point3D { 

    public float X { get; private set; } 
    public float Y { get; private set; } 
    public float Z { get; private set; } 

    public Point3D(float x, float y, float z) { 
     X = x; 
     Y = y; 
     Z = z; 
    } 

    public Point3D Invert() { 
     return new Point3D(-X, -Y, -Z); 
    } 

} 
+0

ग्रेट पोस्ट, आज मेरा आखिरी उपरांत ले लिया। –

+4

यह शायद पाठक कीवर्ड का एक अच्छा उपयोग है, यानी एक्स, वाई और जेड को गुणों के रूप में घोषित करने के बजाय, आप केवल पढ़ने वाले फ़ील्ड प्राप्त कर सकते हैं। लाभ यह होगा कि आप गलती से अपनी अपरिवर्तनीयता को तोड़ नहीं देंगे। – Ant

+0

'myRect = नया आयताकार (myRect.X, myRect.Y + 4, myRect.Width, myRect.Height) है;' वास्तव में 'myRect.Y + = 4;' से स्पष्ट है? Structs के लिए म्यूटेटिंग * विधियों * समस्याग्रस्त हैं, लेकिन कई मामलों में खुला क्षेत्रों को आदर्श होना चाहिए। – supercat

2

बड़ी चिंता यह है कि स्मृति को ढेर या ढेर पर आवंटित किया गया है या नहीं। स्ट्रक्चर डिफ़ॉल्ट रूप से स्टैक में जाते हैं, और स्टैक आमतौर पर अंतरिक्ष के मामले में अधिक सीमित होता है। इसलिए इस तरह के structs का एक पूरा समूह बनाना एक समस्या हो सकती है।

प्रैक्टिस में, हालांकि, मुझे सच में नहीं लगता कि यह एक सौदा का बड़ा है। यदि आपके पास उनमें से कई हैं तो वे कहीं भी कक्षा के उदाहरण (ढेर पर) का हिस्सा हैं।

+1

स्टैक स्पेस structs के लिए चिंता नहीं है, क्योंकि आपके पास शायद ही कभी कई स्थानीय चर हैं। यदि आप structs की सरणी बनाते हैं तो इसे ढेर पर आवंटित किया जाएगा, न कि स्टैक। – Guffa

+0

मुझे लगता है कि यह मेरा मुद्दा था: यदि आप _do_ में बहुत से समस्याएं हैं, लेकिन आपको उन लोगों की संभावना नहीं है। –

+0

यदि आपके पास बहुत से चर हैं तो यह एक समस्या है या नहीं, चाहे यह एक संरचना या कक्षा है, क्योंकि संदर्भ स्टैक पर भी आवंटित किए जाएंगे ... :) – Guffa

1

वैल्यू प्रकार (संरचना) प्रकार के लिए अच्छे हैं जो अक्सर ढेर पर आवंटित नहीं होते हैं, यानी, वे अधिकतर किसी अन्य संदर्भ या मूल्य प्रकार में निहित होते हैं।

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

+0

धन्यवाद, इसलिए स्थानीय चर के रूप में उपयोग किए जाने पर स्ट्रक्चर केवल ढेर पर होंगे, और कुछ भी नहीं? –

+0

नहीं, यह दूसरी तरफ है। संरचना की तरह एक मान प्रकार केवल स्टैक पर आवंटित किया जाता है यदि यह स्थानीय चर है। यदि यह किसी वर्ग का सदस्य है, तो इसे ढेर पर ऑब्जेक्ट के मेमोरी एरिया के हिस्से के रूप में आवंटित किया जाता है। – Guffa

2

संरचना इस एप्लिकेशन के लिए सही लगता है।

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

यह देखने के लिए एक बात यह है कि इससे बड़े ऑब्जेक्ट ढेर पर आवंटन होता है। यह स्पष्ट नहीं है कि, अगर बिल्कुल, यह ढेर खुद को डिफ्रैग करता है, हालांकि बहुत लंबे समय तक रहने वाली वस्तुओं के लिए शायद यह कोई मुद्दा नहीं है।

इनमें से लाखों डेटा प्रकारों के लिए कक्षा का उपयोग करना संभवतः इस प्रकार के संचालन के लिए होने वाली डीरफ्रेंसिंग की कतरनी मात्रा में महंगा होगा।

5

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

तो टी [] सरणी में उपयोग के लिए structs अधिक कुशल हैं।

2

एक नियम के रूप में, गैर-उपनाम के बड़े सरणी (यानी।unshared) एक ही प्रकार का डेटा प्रदर्शन के लिए structs में सबसे अच्छा संग्रहित है क्योंकि आप संकेतों की संख्या को कम करते हैं। (when-are-structs-the-answer भी देखें)। कक्षा और संरचना के बीच सटीक प्रदर्शन अंतर आपके उपयोग पर निर्भर करता है। (उदाहरण के लिए, क्या आप केवल संरचना के हिस्सों तक पहुंचते हैं? क्या आप बहुत अस्थायी प्रतिलिपि करते हैं? यदि संरचना छोटी है तो शायद यह हमेशा उपयोग करने के लिए बेहतर है, लेकिन यदि यह बड़ा है, तो अस्थायी प्रतियां बनाना आपको धीमा कर सकता है। अगर आप इसे अपरिवर्तनीय बनाएं आपको मूल्य को बदलने के लिए हमेशा पूरी चीज की प्रतिलिपि बनाना होगा।)

संदेह में, उपाय करें।

जब से तुम संभव दीर्घकालिक प्रभाव है कि इस तरह के एक माप द्वारा स्पष्ट नहीं हो, ध्यान रखें कि इस तरह के सरणियों की संभावना बड़े वस्तु ढेर पर जमा हो जाती है और फिर से इस्तेमाल किया जाना चाहिए बजाय नष्ट कर दिया और फिर से हो सकता है में रुचि रखते हैं आवंटित। (CRL Inside Out: Large Object Heap Uncovered देखें।)

कॉल में बड़े आकार के structs को पारित करते समय आप प्रतिलिपि से बचने के लिए उन्हें रेफरी तर्क के साथ पास करना चाहते हैं।