2012-03-08 8 views
9

मैं अभी भी सी # के लिए काफी नया हूं, लेकिन विशिष्ट मामलों में List के बजाय HashSet का उपयोग करने के फ़ोरम पोस्टिंग के माध्यम से फायदे देखे।हैशसेट पर फिर से शुरू करने के लिए सबसे तेज़/सुरक्षित तरीका क्या है?

मेरा वर्तमान मामला यह नहीं है कि मैं एक List में बहुत अधिक मात्रा में डेटा संग्रहीत कर रहा हूं, लेकिन इसके बजाय मुझे अक्सर इसके सदस्यों की जांच करनी पड़ती है।

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

मैंने पढ़ा है कि प्रत्येक लूप के लिए वास्तव में अगले के मुकाबले धीमी गति से है, तो मैं सबसे तेज़ विधि में इसके बारे में और कैसे जा सकता हूं?

.Contains() चेक की संख्या मैं निश्चित रूप से सूचियों के साथ अपना प्रदर्शन प्रभावित कर रहा हूं, इसलिए कम से कम HashSet के प्रदर्शन की तुलना करना आसान होगा।

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

यदि मेरे प्रश्न का सीधा जवाब नहीं है, तो यह ठीक है, लेकिन मुझे लगता है कि HashSet पर foreach चक्र से अधिक पुनरावृत्त करने के अन्य तरीके हो सकते हैं। मैं वर्तमान में अंधेरे में हूं कि अन्य तरीकों से क्या हो सकता है, वे क्या फायदे प्रदान करते हैं, आदि। मान लीजिए कि अन्य विधियां भी हैं, मैंने यह भी धारणा की है कि पसंद की एक सामान्य पसंदीदा विधि होगी जिसे केवल अनदेखा किया जाता है यह जरूरतों को पूरा नहीं करता है (मेरी ज़रूरतें बहुत बुनियादी हैं)।

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

+1

पुनरावृत्ति में आप क्या करने की योजना बना रहे हैं? कोड निष्पादित करें? कुछ गिनें? –

+3

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

+1

मुझे उत्तर के बारे में कुछ भी पता नहीं है, लेकिन मेरा सम्मेलन कहता है कि सबसे तेज़ तरीका सबसे सुरक्षित नहीं होगा और सबसे सुरक्षित सबसे तेज़ नहीं होगा। मेरा मानना ​​है कि यदि एक विधि दोनों सबसे तेज़ और सुरक्षित है, तो वहां कोई और तरीका नहीं होना चाहिए। शायद मैं गलत हो सकता हूँ। – nawfal

उत्तर

8

एक फ़ोरैच लूप में अनुक्रमित संग्रह (जैसे सरणी) पर अतिरिक्त ओवरहेड होता है। यह ज्यादातर इसलिए है क्योंकि फोरच लूप के मुकाबले थोड़ी अधिक सीमाओं की जांच करता है।

हैशसेट में इंडेक्सर नहीं है इसलिए आपको गणनाकर्ता का उपयोग करना होगा।

इस मामले में foreach कुशल है क्योंकि यह केवल MoveNext() को कॉल करता है क्योंकि यह संग्रह के माध्यम से चलता है।

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

जैसा कि प्रोफाइलिंग से पहले बताया गया है आपकी सबसे अच्छी शर्त है।

4

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

+6

वह अपने प्रश्न में कहता है कि उसे खोज और पुनरावृत्ति दोनों को सक्षम करने की आवश्यकता है, खोज करने के लिए पुन: प्रयास नहीं। – JamieSee

2

सख्ती से शीर्ष लेख में सवाल का जवाब नहीं है, लेकिन अधिक अपने विशिष्ट समस्या के विषय में: मैं अपने खुद के Collection वस्तु दोनों एक HashSet और एक List का उपयोग करता है आंतरिक रूप से बनाना होगा

। इटरेटिंग तेज़ है क्योंकि आप सूची का उपयोग कर सकते हैं, Contains की जांच तेज है क्योंकि आप हैशसेट का उपयोग कर सकते हैं। बस इसे IEnumerable बनाएं और आप इस संग्रह का उपयोग foreach में भी कर सकते हैं।

नकारात्मक पक्ष अधिक स्मृति है, लेकिन ऑब्जेक्ट के लिए केवल दो बार संदर्भ हैं, कई ऑब्जेक्ट्स नहीं। सबसे खराब स्थिति परिदृश्य यह केवल दोगुनी स्मृति है, लेकिन आप प्रदर्शन से ज्यादा चिंतित हैं।

जोड़ना, जांचना और पुनरावृत्ति करना इस तरह से तेज़ है, List की वजह से केवल हटाने अभी भी ओ (एन) है।

संपादित करें: अगर हटाने को ओ (1) होना चाहिए, तो इसे एक डबल पॉइंटर सूची बनाएं, और हैशसेट को एक शब्दकोश बनाएं ताकि आप सूची में ऑब्जेक्ट का स्थान तेजी से पा सकें।

0

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

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