2011-07-20 13 views
79

मेरे पास Map<String, String> testMap = new HashMap<String, String>(); के रूप में वाक्यविन्यास के रूप में एक मानचित्र है। इस मानचित्र में 1000 डेटा हो सकते हैं।Map.clear() बनाम नया मानचित्र: कौन सा बेहतर होगा?

जब मेरे एप्लिकेशन को डेटा की नई सूची की आवश्यकता होती है, तो मुझे मानचित्र को साफ़ करना होगा। लेकिन जब मैं

/** 
    * Removes all of the mappings from this map. 
    * The map will be empty after this call returns. 
    */ 
    public void clear() { 
     modCount++; 
     Entry[] tab = table; 
     for (int i = 0; i < tab.length; i++) 
      tab[i] = null; 
     size = 0; 
    } 

रूप Map.clear() के कोड को देखा मुझे लगता है कि स्पष्ट विधि n समय के लिए पाश में चला जाता है (जहाँ n मानचित्र में डेटा की संख्या है)। तो मैंने सोचा कि उस मानचित्र को testMap = new HashMap<String, String>(); के रूप में फिर से परिभाषित करने का एक तरीका हो सकता है और पहले इस्तेमाल किया गया मानचित्र कचरा एकत्रित किया जाएगा।

लेकिन मुझे यकीन नहीं है कि यह एक अच्छा तरीका होगा। मैं मोबाइल एप्लिकेशन पर काम कर रहा हूं।

क्या आप कृपया मुझे मार्गदर्शन कर सकते हैं?

+1

लंबे समय से पहले इस प्रश्न को पोस्ट किया गया था, लेकिन फिर भी, Google हमें इसकी मार्गदर्शिका जारी रखता है। तो नए पर स्पष्ट उपयोग करने का एक और फायदा। आप मानचित्र को अंतिम के रूप में घोषित करने में सक्षम होंगे और इसलिए संकलक प्रोग्रामिंग कीड़े को मुफ्त में पहचानने में सक्षम होंगे। अन्य प्रकार की संरचनाओं के लिए "अंतिम" हमारे कोड (बहुत) तेज़ी से नई मेमोरी आवंटित करने का बोझ भी हटा देगा। – earizon

उत्तर

74

जटिल प्रश्न बनाने बेहतर है। चलिए देखते हैं क्या होता है।

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

वैसे भी, दोनों प्रकारों को आजमाएं और मापने का प्रयास करें। हमेशा उपाय करें!

+1

+1 पढ़ने के बाद धन्यवाद , मुझे एहसास हुआ कि मैं उलझन में था। धन्यवाद। –

+0

@ Tanveer के उत्तर पर मेरी टिप्पणी देखें। आप जीसी की लागत का अनुमान नहीं लगा सकते हैं। – Jason

1

map.clear() जो सभी डेटा को हटा देगा। ध्यान दें कि यह केवल सभी प्रविष्टियों को त्याग देगा, लेकिन आंतरिक सरणी को उसी आकार में प्रविष्टियों को संग्रहीत करने के लिए उपयोग किया जाता है (प्रारंभिक क्षमता को कम करने के बजाए)। यदि आपको इसे खत्म करने की भी आवश्यकता है, तो संपूर्ण हैश मैप को त्यागना और इसे एक नए उदाहरण के साथ बदलना सबसे आसान तरीका होगा। यह निश्चित रूप से केवल तभी काम करता है जब आप नियंत्रित करते हैं कि मानचित्र पर पॉइंटर कौन है।

स्मृति को पुनः प्राप्त करने के लिए, आपको कचरा कलेक्टर अपना काम करने देना होगा।

क्या आपके मूल्य भी लंबे हैं? इस मामले में, आप जेनेरिक हैश मैप की तुलना में अधिक (मेमोरी-) कुशल कार्यान्वयन को देखना चाहेंगे, जैसे GNU Trove library में मिले TLongLongHashMap। इससे बहुत सारी यादें बचाई जानी चाहिए।

5

स्पष्ट() विधि रखने का विचार मानचित्र से अन्य ऑब्जेक्ट्स के संदर्भों को हटाने के लिए है, ताकि "मानचित्र कहीं और संदर्भित किया गया हो" तो कुंजी/मान जिंगिंग से नहीं बनाए जाते हैं।

लेकिन यदि आपका नक्शा केवल एक स्थानीय मानचित्र है जो केवल आपके विशिष्ट कोड द्वारा उपयोग किया जाता है (यानी "नक्शा 'कहीं और संदर्भित नहीं है") तो आगे बढ़ें और इसके बजाय एक नया मानचित्र उपयोग करें, लेकिन शून्य संदर्भों के लिए 1000 संदर्भ सेट करें वैसे भी एक बड़ा प्रदर्शन मारा।

+1

हां यह 1000 संदर्भों के लिए एक बड़ा प्रदर्शन हिट नहीं होगा। मैं इस बारे में पूछ रहा था कि एक नया उदाहरण बनाना स्पष्ट विधि से बेहतर है या नहीं। और क्या नया उदाहरण उपयोग करने में कोई कमी है? –

+1

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

+1

+1 अच्छे उत्तर के लिए धन्यवाद –

1

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

7

मैं जावा स्मृति के मामले में और अधिक महंगी में वस्तु बनाया जा रहा है सोचा, तो यह आप, .clear() साथ जाने के लिए ताकि आप एक ही वस्तु का उपयोग कर रहे बजाय नया एक

+1

+1 अच्छा उत्तर –

0

नक्शा

के repopulation मत भूलना अगर आप नए नक्शे पर क्षमता आप क्योंकि rehashes के नव निर्मित मानचित्र पर काफी भूमि के ऊपर का एक सा मिल जाएगा (जो एक हे हैं निर्दिष्ट नहीं करते (एन) (उस समय) और ओ (लॉग (एन)) बार होता है, जबकि यह कुल (ओ) कुल में हो सकता है लेकिन यदि वे पहले स्थान पर नहीं होते हैं तो भी आप बेहतर होंगे)

इस मंजूरी दे दी नक्शे के साथ नहीं होगा क्योंकि क्षमता

20

परिवर्तन नहीं होता है जब आप आकार n का एक मानचित्र पर कहते हैं कि Map.clear() ... आप 2*n (कुंजी & वैल्यू) ऑब्जेक्ट्स को साफ करने के लिए जीसी से पूछ रहे हैं। जब आप उसी मानचित्र पर null कहते हैं, तो आप जीसी को 2*n+1 (मानचित्र के लिए 1) ऑब्जेक्ट्स को साफ़ करने के लिए कह रहे हैं। फिर आपको एक नया मैप इंस्टेंस बनाना होगा, फिर भी एक और ओवरहेड। तो Map.clear() के लिए जाएं। इसे तुरंत चालू करते समय मानचित्र के आकार को पूर्व निर्धारित करना बुद्धिमान होगा।

+1

बड़े ओ अनुमान आपको केवल तभी लागू होते हैं जब मानचित्र में कुंजी और मानों को कहीं और संदर्भित नहीं किया जाता है। यदि आवेदन में कहीं और किसी भी कुंजी और मानों का संदर्भ दिया जाता है तो वे एकत्रित कचरा नहीं होंगे। शायद मुझे गलत लगता है कि "साफ करें" से आपका मतलब है कि कचरा कलेक्टर को यह देखने के लिए ऑब्जेक्ट की जांच करनी चाहिए कि उसे कचरा इकट्ठा करने की आवश्यकता है या नहीं। यहां एक और बिंदु है ... कचरा कलेक्टर ऑब्जेक्ट को साफ़ कर सकता है भले ही उनके पास कोई संदर्भ न हो: http://stackoverflow.com/a/2506525/361855। मेरा मुद्दा यह है कि आप नक्शा रेफरी बदलते समय जीसी की लागत का अनुमान नहीं लगा सकते हैं। – Jason

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