2013-06-17 10 views
9

जिज्ञासा और दक्षता इस प्रश्न के कारण हैं। मैं एक स्थिति में हूँ जहाँ मैं कई नए HashSets बनाने रहा हूँ के बाद कुछ छोरों चलाएँ:एक हैशसेट बनाम एक साफ़ हैशसेट बनाम मेमोरी प्रभावशीलता

HashSet वर्तमान वर्ग के शीर्ष पर इस तरह के रूप में घोषित किया जाता है: बाद में कोड में फिर

private Set<String> failedTests; 

, मैं सिर्फ जब भी मैं परीक्षण फिर से चला रहा हूँ एक नया failedTests HashSet बनाएँ:

failedTests = new HashSet<String>(16384); 

मैं इस अधिक से अधिक करते हैं, परीक्षण के आकार के आधार। मैं कचरा कलेक्टर को पुराने डेटा को सबसे कुशलतापूर्वक संभालने की अपेक्षा करता हूं। लेकिन, मैं जानता हूँ कि एक और विकल्प शुरुआत में शुरू में HashSet बनाने के लिए होगा:

private Set<String> failedTests = new HashSet<String>(16384); 

और फिर पाश के माध्यम से HashSet हर बार साफ़ करें।

failedTests.clear(); 

मेरा प्रश्न यह है कि ओवरहेड आदि के मामले में ऐसा करने का सबसे प्रभावी तरीका कौन सा है? मुझे नहीं पता कि स्पष्ट() फ़ंक्शन क्या कर रहा है - क्या यह वही काम कर रहा है, पुराने डेटा को कचरा संग्रह में भेज रहा है, या यह कुछ और अधिक कुशल कर रहा है? इसके अलावा, मैं हैशसेट को प्रारंभिक क्षमता का एक बड़ा कुशन दे रहा हूं, लेकिन यदि किसी परीक्षण के लिए 2^14 तत्वों की आवश्यकता होती है, तो .clear() फ़ंक्शन हैशसेट को 16384 पर फिर से चालू करेगा?

जोड़ने के लिए, मुझे source code to clear() here मिला। तो यह कम से कम एक ओ (एन) ऑपरेशन सबसे खराब मामले है।

स्पष्ट फ़ंक्शन का उपयोग करके, मैंने एक परीक्षण प्रक्रिया की जो 565 सेकंड में समाप्त हुआ। इसे संभालने के लिए जीसी का उपयोग करके, परीक्षण 506 सेकंड में समाप्त हुआ।

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

+0

क्या आपने इसे बेंचमार्क करने का प्रयास किया है? – rob

+0

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

+0

संभावित डुप्लिकेट [लूप में ArrayList को फिर से बनाने के लिए सबसे तेज़ तरीका] (http://stackoverflow.com/questions/11740013/fastest-way-to-recreate-the-arraylist-in-a-for-loop): 'नया' आम तौर पर 'स्पष्ट' से तेज है। – assylias

उत्तर

6

मैं नहीं जानता कि क्या स्पष्ट() फ़ंक्शन

यह HashMap तालिका के clear() विधि है कि वह आंतरिक रूप से उपयोग कर रहा है बुला रहा है अंदर कर रही है।

public void clear() { 
    modCount++; 
    Entry[] tab = table; 
    for (int i = 0; i < tab.length; i++) 
     tab[i] = null; 
    size = 0; 
} 

यह एक ही बात कर रहा है, कचरा संग्रह करने के लिए पुराने डेटा भेजने, या उसे और अधिक कार्यकुशल कुछ कर रहा है: HashMap भीतर clear() विधि इस प्रकार परिभाषित किया गया है?

tab[i] = null बताता है कि यह पुराने डेटा को कचरा संग्रह के लिए योग्य बना रहा है।

इसके अलावा, मैं HashSet आरंभिक क्षमता की एक बड़ी तकिया , होगा .clear दे रहा हूँ, लेकिन अगर एक परीक्षण अधिक से अधिक 2^14 तत्वों की आवश्यकता होती है() फ़ंक्शन फिर से दृष्टांत 16384 करने के लिए HashSet?

नहीं, यह नहीं होगा।

जो ओवरहेड, आदि के मामले में ऐसा करने का सबसे प्रभावी तरीका है?

मुझे लगता है, जावा कचरा कलेक्टर जानता है कि अपने काम को सबसे कुशल तरीके से कैसे करना है। तो कचरा कलेक्टर को इसकी देखभाल करने दें। इसलिए, मैं हर बार एक नई विफलता HashSet बनाने की आवश्यकता होगी।

+2

बड़ी वस्तुएं सीधे कार्यरत स्थान पर जाती हैं, इसलिए यह जीसी के मुकाबले ज्यादा महंगा है नर्सरी पीढ़ी में जीसी छोटी वस्तुओं के लिए। फिर भी, यह लागत बैकिंग सरणी के सभी 16000 तत्वों के माध्यम से पुनरावृत्ति की लागत की तुलना में पेलेस करती है। –

4

हैशसेट को पुनर्निर्मित करना अधिक कुशल है।

1) यदि HashSet क्षमता 16384 स्पष्ट आरंभिक क्षमता के लिए इसे रीसेट नहीं होंगे

2) नए HashSet (16384) से ऊपर की वृद्धि हुई एक नई एंट्री [16384] सरणी, यह है एक आपरेशन, यह nulling तत्वों से अधिक कुशल है बनाता है एक जैसा स्पष्ट है

for (int i = 0; i < table.length; i++) 
    tab[i] = null; 
संबंधित मुद्दे