2012-06-28 9 views
9

हाल ही में मुझे सिंगलटन क्लास के साथ कुछ समस्याएं थीं जो आलसी शुरू करने वाले आलसी थे जहां एक दूसरा धागा वास्तव में पॉप्युलेट होने से पहले इसका उपयोग करने का प्रयास करेगा। इसलिए मैंने Lazy<T> कक्षा के माध्यम से परिवर्तनीय प्रारंभिकरण लागू किया।प्रदर्शन के लिए आलसी <T> खराब है?

private static Dictionary<string, string> GroupDefaults 
{ 
    get { return mGroupDefaults.Value; } 
} 
private static Lazy<Dictionary<string, string>> mGroupDefaults = 
    new Lazy<Dictionary<string,string>>(delegate 
    { 
     Dictionary<string, string> defaults = new Dictionary<string, string>(); 
     foreach (KeyValuePair<string, UnitGroup> groupDef in Groups) 
      defaults.Add(groupDef.Key, groupDef.Value.First().Key); 
     return defaults; 
    }); 

यह समस्या ठीक हो गई है और अब मैं इस Lazy<T> वर्ग का उपयोग करने के मेरा एक नियमित अभ्यास कर रही है पर विचार कर रहा हूँ कहीं मैं आलसी प्रारंभ करना किसी भी संभव सूत्रण मुद्दों से बचने के:

यहाँ मेरी कोड है। तो मूल रूप से मैं जानना चाहता हूं कि यह अच्छा/सामान्य अभ्यास है या नहीं? या यह प्रदर्शन या कुछ के लिए हानिकारक होगा?

उत्तर

10

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

+0

तो यह आलसी कक्षा का उपयोग करने के लिए एक अच्छा अभ्यास है? –

+2

@ AlexHopeO'Connor यही कारण है कि इसे जोड़ा गया था! कक्षा का उपयोग करने का नकारात्मक हिस्सा यह है कि क्षेत्र/संपत्ति की घोषणा थोड़ा गड़बड़ हो जाती है (जैसा कि आप देख सकते हैं) लेकिन प्रदर्शन के अनुसार, यह ठोस है। – dlev

+2

मुझे जो कुछ सुनने की ज़रूरत है, वहीं मैंने इसे अन्य लोगों के कोड में कई उदाहरण नहीं देखा है। –

1

मुझे लगता है कि आप इसका उपयोग करने के लिए आलसी का उपयोग नहीं कर सकते हैं। आलसी उन परिस्थितियों के लिए उपयोग की जानी चाहिए जहां कुछ बड़ी प्रारंभिक लागत है, लेकिन एक संभावित मौका है कि इसका उपयोग ऑब्जेक्ट के जीवनकाल के दौरान नहीं किया जा सकता है।

आप हमेशा GroupDefaults कम से कम एक बार कॉल प्रति यह जीवन एक बेहतर तरीका कंटेनर के जीवनकाल के शुरू में एक पृष्ठभूमि सूत्र में GroupDefaults प्रारंभ और आशा है कि यह पहले यह आरंभ किया जाता है किया जाता है के लिए होगा है (मैं जानता हूँ कि वहाँ है इसके लिए एक वर्ग लेकिन मुझे इसे खोजने के लिए एमएसडीएन में खोदने की जरूरत है)

+1

नहीं है, जबकि मैं सहमत हूं कि यह इच्छित उपयोग केस है, यह * थ्रेड-सुरक्षित प्रारंभिक रूप से सही ढंग से लागू करता है, इसलिए आपको चिंता करने की ज़रूरत नहीं है खुद ऐसा करने के बारे में। – dlev

+0

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

2

यदि यह सिंगलटन के लिए है, तो static constructor जो भी आप चाहते हैं हो सकता है। कुछ की तरह:

class MySingleton 
{ 
    static MySingleton() 
    { 
     Instance().InitDict(); 
    } 
} 
3

प्रलेखन से, मैं निम्नलिखित है:

कोई प्रतिनिधि लेज़ी निर्माता में पारित हो जाता है, तो लिपटे प्रकार Activator.CreateInstance उपयोग करके बनाया जाता है जब मूल्य संपत्ति पहले पहुंचाया गया है। यदि इस प्रकार के पास डिफॉल्ट कन्स्ट्रक्टर नहीं है, तो रन-टाइम अपवाद फेंक दिया जाता है।

Activator.CreateInstance एक ऐसी विधि है जो प्रदर्शन के लिए कुख्यात रूप से खराब है। हालांकि, यह आपके मामले में कोई समस्या नहीं प्रतीत होता है, और किसी भी दर पर, जैसा कि डीएलवी ने कहा था, एक बार विधि का आह्वान करना कोई समस्या नहीं होगी। मैंने Lazy<T> को अक्सर नहीं देखा है, लेकिन मुझे आपके मामले में इसका उपयोग न करने का कोई कारण नहीं दिख रहा है।

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