2012-04-18 6 views
52

निम्नलिखित enum को देखते हुए:मुझे बाइट के बजाय एनम इंट 32 का अंतर्निहित प्रकार क्यों बनाना चाहिए?

public enum Operations_PerHourType : byte 
{ 
    Holes = 1, 
    Pieces = 2, 
    Sheets = 3, 
    Strips = 4, 
    Studs = 5 
} 

जब मैं माइक्रोसॉफ्ट कोड विश्लेषण उपकरण चलाने के लिए, यह मुझसे कहता है:

CA1028: Microsoft.Design: यदि संभव हो, 'Enums के अंतर्निहित प्रकार हैं। 'बाइट' के बजाय Operations_PerHourType 'System.Int32।

इसमें दो संभावित मूल्यों से अधिक कभी नहीं होगा, इसलिए मैंने इसे बाइट के रूप में घोषित किया। वे int32 का उपयोग करने की सिफारिश क्यों करेंगे? भविष्य में स्केलेबिलिटी के लिए अधिक मूल्य? या क्या कोई प्रदर्शन सुधार है?

+5

स्टोरेज एक बाइट या इंट क्यों है या नहीं? बाइट के उपयोग को मजबूर करने की कोशिश में आपकी प्रेरणा क्या है? –

+4

मैंने तब तक नहीं किया जब तक कि मैं माइक्रोसॉफ्ट कोड विश्लेषण उपकरण चलाता हूं। यह एक Int32 का उपयोग करने की सिफारिश की। मैं उत्सुक हूँ क्यों। मैंने शुरुआत में बाइट का इस्तेमाल किया क्योंकि मुझे लगता है कि यह प्रदर्शन के लिए बेहतर होगा। कम जगह। – Kevin

+1

http://stackoverflow.com/questions/5005319/why-cant-i-declare-an-enum-inheriting-from-byte-but-i-can-from-byte –

उत्तर

40

कारण के लिए MSDN पर एक नज़र डालें।

एक गणन एक मूल्य के प्रकार है कि संबंधित नामित स्थिरांक का एक सेट को परिभाषित करता है:

यहाँ एक अंश है। डिफ़ॉल्ट रूप से, System.Int32 डेटा प्रकार का उपयोग निरंतर मान को संग्रहीत करने के लिए किया जाता है। भले ही आप इस अंतर्निहित प्रकार को बदल सकें, यह आवश्यक है या अधिकांश परिदृश्यों के लिए अनुशंसित नहीं है। ध्यान दें कि महत्वपूर्ण प्रदर्शन लाभ डेटा प्रकार का उपयोग करके प्राप्त किया जाता है जो Int32 से छोटा है। यदि आप डिफ़ॉल्ट डेटा प्रकार का उपयोग नहीं कर सकते हैं, तो आप को सामान्य भाषा प्रणाली (सीएलएस) -compliant integral प्रकार, बाइट, Int16, Int32, या Int64 का उपयोग करना चाहिए ताकि यह सुनिश्चित किया जा सके कि के सभी मानों का प्रतिनिधित्व किया जा सके सीएलएस-अनुरूप प्रोग्रामिंग भाषाएं।

+0

बहुत बहुत धन्यवाद। – Kevin

21

प्रलेखन के अनुसार, वहाँ int32 के बजाय एक बाइट का उपयोग करने से कोई प्रदर्शन लाभ है। ऐसा करने का कोई कारण नहीं है, वे इसे बदलने की सलाह देते हैं। अंतर्निहित विचार यह है कि .NET को कई परिदृश्यों में INT32 का उपयोग करने के लिए अनुकूलित किया गया है, और उन्होंने एक कारण के लिए enums के लिए चुना है। आपको इसे बदलकर अपने परिदृश्य में कुछ भी नहीं मिलता है, तो परेशान क्यों करें।

http://msdn.microsoft.com/en-us/library/ms182147.aspx

यह भी कैसे नेट 32 बिट पूर्णांकों उपयोग करने के लिए अनुकूलित है के बारे में वार्ता: .NET Optimized Int32

+2

यह .NET नहीं है जिसे INT32 का उपयोग करने के लिए अनुकूलित किया गया है, बल्कि अंतर्निहित CPU, सबसे विशेष रूप से असेंबली निर्देश ऑपरेंड के रजिस्टर आकार/आकार के कारण - जो कि 32 बिट सिस्टम पर 32 बिट होता है। यदि मूल्य का आकार अलग है तो इसे गठबंधन/गद्देदार और अतिरिक्त सीपीयू चक्रों की आवश्यकता होती है। दिलचस्प बात यह है कि आपके द्वारा जुड़े धागे में इसका उल्लेख किया गया है। अधिकतर ओवरहेड न्यूनतम है। मुद्दा यह है कि प्रदर्शन कारणों से INT32 के बजाय BYTE का उपयोग वास्तव में विपरीत प्रभाव होगा। प्रत्येक एचएल भाषा के मामले में मामला है। –

+1

@SaschaHennig - वह धागा अच्छा, लेकिन अपूर्ण पृष्ठभूमि देता है। यह भी पढ़ें: http://stackoverflow.com/questions/1054657/memory-alignment-on-a-32-bit-intel- प्रोसेसर यह जानने के लिए कि आपका इंट 32 आधारित एनम कभी-कभी 8 बाइट्स क्यों लेता है स्ट्रक्चर लेआउट, और यह माइक्रोसॉफ्ट द्वारा किए गए प्रदर्शन से संबंधित है, डबल एज किए गए फैसले जिसे आप ओवरराइड कर सकते हैं यदि आप जानते हैं कि आप क्या कर रहे हैं। यह फ्रेमवर्क या हार्डवेयर नहीं है जो प्रभारी है। वे साथ साथ काम करते हैं। –

+0

@ जिर्का हनिका - दिलचस्प पढ़ा, धन्यवाद।कोई भी एचएल भाषा केवल हार्डवेयर के संदर्भ में चर (या वास्तव में कुछ भी) के उपयोग को अनुकूलित कर सकती है। फिर भी यह न तो ढांचा या हार्डवेयर है जो प्रभारी है, परमतः यह कोडर है। –

21

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

इस नमूने पर विचार करें:

using System; 

public enum Operations_PerHourType // : byte 
{ 
    Holes = 1, 
    Pieces = 2, 
    Sheets = 3, 
    Strips = 4, 
    Studs = 5 
} 

class Program 
{ 
    static void Main() 
    { 
     long before = GC.GetTotalMemory(false); 
     var enums = new Operations_PerHourType[10000]; 
     long after = GC.GetTotalMemory(false); 

     Console.WriteLine(after - before); 
     // output (byte): 12218 (I'm using Mono 2.8) 
     // output (Int32): 40960 
    } 
} 

इस कोड की खपत लगभग 40 ढेर के KB। अब अंतर्निहित प्रकार को byte के रूप में निर्दिष्ट करें (असम्बद्ध) और पुन: संकलित करें। वाह। अचानक हमें केवल 10 केबी की जरूरत है।

इस तरह की स्मृति को संपीड़ित करने से कभी-कभी विशेष पहुंच पैटर्न और डेटा आकारों के आधार पर प्रोग्राम धीमा नहीं हो सकता है। कुछ माप करने और अन्य संभावित परिस्थितियों को सामान्यीकृत करने का प्रयास करने के लिए निश्चित रूप से जानने का कोई तरीका नहीं है। छोटे डेटा का अनुक्रमिक ट्रैवर्सल आमतौर पर तेज़ होता है।

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

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

+0

अन्य टिप्पणियों में कुछ गलतफहमी का सामना करने के लिए उत्कृष्ट बिंदु। –