2013-10-24 13 views
12

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

तो मेरा सवाल यह है कि मानचित्र को खाली करने के लिए एक बेहतर तरीका क्या है? क्या मुझे इसे हर बार शून्य पर सेट करना चाहिए या क्या मुझे clear() पर कॉल करना चाहिए? मुझे पता है कि समय में स्पष्ट रैखिक है। लेकिन मुझे नहीं पता कि हर समय मानचित्र बनाने के साथ उस लागत की तुलना कैसे करें। मानचित्र का आकार स्थिर नहीं है, सोचा कि यह रचनाओं के बीच एन से 3 एन तत्वों से चलाया जा सकता है।

उत्तर

7

एक नक्शे के अन्य वस्तुओं जहां यह एक नया सेट करने के लिए मुश्किल हो सकता है से संदर्भित नहीं है, तो बस null एक पुराने नक्शे बाहर आईएनजी और शून्य से शुरू, एक clear() बुला से शायद हल्का वजन है, क्योंकि कोई रैखिक समय सफाई की जरूरत है। कचरा संग्रहण लागत आधुनिक प्रणालियों पर छोटे होने के साथ, एक अच्छा मौका है कि आप इस तरह के कुछ CPU चक्रों को बचाएंगे। प्रारंभिक क्षमता निर्दिष्ट करके आप मानचित्र को कई बार आकार देने से बच सकते हैं।

एक स्थिति जहां clear() पसंदीदा है जब नक्शा ऑब्जेक्ट आपके सिस्टम में एकाधिक ऑब्जेक्ट्स के बीच साझा किया जाता है। उदाहरण के लिए, यदि आप कोई नक्शा बनाते हैं, तो इसे कई ऑब्जेक्ट्स दें, और उसके बाद कुछ साझा जानकारी रखें, इन सभी ऑब्जेक्ट्स में मानचित्र को किसी नए स्थान पर सेट करने के लिए मानचित्र वाले ऑब्जेक्ट्स के संदर्भों को रखने की आवश्यकता हो सकती है। ऐसी स्थितियों में, उसी साझा मानचित्र ऑब्जेक्ट पर clear() पर कॉल करना आसान है।

+0

"उदाहरण के लिए, यदि आप कोई नक्शा बनाते हैं, तो इसे कई ऑब्जेक्ट्स दें ..." क्या आपका सामान्य मानचित्र (मानचित्र <ऑब्जेक्ट, ऑब्जेक्ट>) के लिए है? – Woody

+0

@Woody मेरा मतलब है 'मानचित्र ' इंटरफ़ेस - 'हैश मैप ' या 'ट्रीएप ' लागू करने वाला एक वर्ग बनाना। – dasblinkenlight

+1

@Woody - मुझे नहीं लगता कि यह क्यों मायने रखता है। उनका मतलब है कि यदि ऐसी कई वस्तुएं हैं जिनके पास मूल मानचित्र का संदर्भ है, तो आपको शायद मानचित्र को खाली करने के चरण में 'स्पष्ट() 'का उपयोग करने की आवश्यकता होगी (मानचित्र पर एक संदर्भ को शून्य पर सभी का कोई प्रभाव नहीं होगा एक ही मानचित्र के अन्य संदर्भ)। – jahroy

2

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

Map<String, String> whatever = new HashMap<String, String(); 
// .. do something with map 
whatever = new HashMap<String, String>(); 

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

+5

आपका कोड स्निपेट संकलित नहीं होगा। आपने संदर्भ को 'अंतिम' के रूप में घोषित कर दिया है, इसलिए आप किसी कन्स्ट्रक्टर के साथ जो भी इंगित करते हैं उसे पुन: असाइन नहीं कर सकते हैं। – asteri

+1

हालांकि यह सच है, यह डाउनवोट का कारण नहीं होना चाहिए (संभवतः उसने आदत से _final_ लिखा था)। – jahroy

+1

@jahroy सहमत हुए। यह एक बड़ा सौदा नहीं है और उसके अंक अभी भी वैध हैं। ओपी के लाभ के लिए बस इसे इंगित किया। – asteri

0

मुझे लगता है कि मौजूदा मानचित्र को clear() से अधिक सस्ता है। आधुनिक जेवीएम में वस्तु का निर्माण बहुत सस्ता है।

0

संक्षिप्त उत्तर: Collection.clear() का उपयोग करें जब तक कि यह collection को चारों ओर रखने के लिए बहुत जटिल न हो।

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

एक और महत्वपूर्ण मुद्दा यह है कि कई वस्तुओं को जारी करने के बाद फिर से कचरा कलेक्टर के अधिक निष्पादन की आवश्यकता होगी, जो अचानक अंतराल का कारण बन सकता है।

+1

@Woody कृपया कोड के लिए केवल 'कोड स्वरूपण' का उपयोग करें, ज़ोर देना नहीं। –

+0

@ पॉल बेलोरा, धन्यवाद, मैंने अभी कोड स्वरूपित किया है और टाइपोग्राफ़िकल त्रुटि ("कचरा कलेक्टर टू कचरा कलेक्टर") को सही किया है। – Woody

+1

हां, फिक्स के लिए धन्यवाद, मैं अपने आईफोन से लिख रहा था। टाइपो के लिए खेद है। – jwatkins

0

यदि आप हमेशा नक्शा रखते हैं, तो यह पुरानी पीढ़ी को संकेत दिया जाएगा। यदि प्रत्येक उपयोगकर्ता के पास एक संबंधित मानचित्र है, तो पुरानी पीढ़ी में मानचित्र की संख्या उपयोगकर्ता की संख्या के अनुपात में होती है। उपयोगकर्ताओं की संख्या में वृद्धि होने पर यह पूर्ण जीसी को अधिक बार ट्रिगर कर सकता है।

0

आप दोनों समान परिणामों के साथ उपयोग कर सकते हैं।

एक पूर्व उत्तर नोट्स कि clear परिपक्व मानचित्र कार्यान्वयन में निरंतर समय लेने की उम्मीद है। HashMap, TreeMap, ConcurrentHashMap की पसंद के स्रोत कोड की जांच किए बिना, मैं अपने clear विधि को लगातार समय लेने के लिए, amortized कचरा संग्रहण लागत की अपेक्षा करता हूं।

एक और पोस्टर नोट करता है कि एक साझा मानचित्र को हटाया नहीं जा सकता है। खैर, अगर आप इसे चाहते हैं, तो आप इसे proxy ऑब्जेक्ट का उपयोग कर कर सकते हैं जो उचित मानचित्र को समाहित करता है और आवश्यकता होने पर इसे बाहर निकाल देता है। बेशक, आपको प्रॉक्सी मैप क्लास को स्वयं लागू करना होगा।

Map<Foo, Bar> myMap = new ProxyMap<Foo, Bar>(); 
    // Internally, the above object holds a reference to a proper map, 
    // for example, a hash map. Furthermore, this delegates all calls 
    // to the underlying map. A true proxy. 
myMap.clear(); 
    // The clear method simply reinitializes the underlying map. 

जब तक आप ऊपर, clear और nulling की तरह कुछ बाहर तरीके कि बात में बराबर हैं, लेकिन मुझे लगता है कि यह अपने नक्शे ग्रहण करने के लिए, भले ही वर्तमान में साझा नहीं किया और अधिक परिपक्व है, एक बाद में साझा हो सकता है किया बलों के कारण समय आप भविष्यवाणी नहीं कर सकते हैं।

नक्शा साझा नहीं होने के बावजूद clear को बाहर निकालने के बजाय एक और कारण है। आपके मानचित्र को बाहरी क्लाइंट द्वारा factory की तरह तुरंत चालू किया जा सकता है, इसलिए यदि आप अपना नक्शा साफ़ करके इसे साफ़ कर देते हैं, तो आप coupling को कारखाने में अनावश्यक रूप से समाप्त कर सकते हैं। मानचित्र को साफ़ करने वाली ऑब्जेक्ट को यह क्यों पता होना चाहिए कि आप अपने मानचित्रों को गुवा के Maps.newHashMap() का उपयोग करके तत्काल मानते हैं कि भगवान क्या पैरामीटर जानते हैं? भले ही यह आपकी परियोजना में यथार्थवादी चिंता न हो, फिर भी यह परिपक्व प्रथाओं के लिए स्वयं को संरेखित करने के लिए भुगतान करता है।

उपर्युक्त कारणों से, और अन्य सभी बराबर होने के कारण, मैं clear के लिए वोट दूंगा।

एचटीएच।

+0

ऐसा लगता है कि 'हैश मैप' की 'स्पष्ट' बाल्टी की संख्या के अनुपात में आनुपातिक है, जो भार के आधार पर तत्वों की संख्या में उपलाइन, सुपरलाइनर या रैखिक हो सकती है। 'TreeMap' में निरंतर समय 'स्पष्ट' विधि है। 'ConcurrentHashMap'' हैश मैप 'की तर्ज पर अधिक है। –

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