2011-01-13 16 views
9

मैं एक हेक्से सी # लक्ष्य लिख रहा हूं, और मैं हेक्से की एसडीडी लाइब्रेरी के प्रदर्शन प्रदर्शनों का अध्ययन कर रहा हूं ताकि हम अपने क्रॉस प्लेटफ़ॉर्म कोड के माध्यम से सर्वोत्तम प्रदर्शन प्रदान कर सकें।सिस्टम। चयन। Generic.Dictionary = अंतिम प्रदर्शन?

हैश तालिका कोड के लिए एक बहुत अच्छा उदाहरण है। मैं .NET के शब्दकोश का उपयोग करने के बारे में थोड़ा अनिच्छुक था, क्योंकि यह भारी लगता है (कुंजी/मूल्य जोड़े के लिए structs मेमोरी संरेखण के मुद्दों के कारण स्मृति की एक बड़ी मात्रा ले सकता है, इसके अलावा अनावश्यक जानकारी के अलावा), और चूंकि std पर लाइब्रेरी में ऑब्जेक्ट हैश जैसी कोई चीज़ नहीं है, मैंने वास्तव में सोचा कि मैं GetHashCode को कॉल न करने के द्वारा थोड़ा प्रदर्शन निचोड़ सकता हूं, और इसे सभी के साथ इनलाइन कर सकता हूं।

यह भी स्पष्ट है कि शब्दकोश कार्यान्वयन टकराव से निपटने के लिए एक लिंक्ड सूची का उपयोग करता है, जो आदर्श से बहुत दूर है।

तो हम IntHash (शब्दकोश) हम पहले Hopscotch hashing कार्यान्वित के साथ शुरू, हमारे अपने समाधान को लागू करने के लिए शुरू कर दिया है, लेकिन यह वास्तव में ना हटे बहुत अच्छी तरह से है, लेकिन यह एक तरह से स्पष्ट है कि यह बहुत अच्छी तरह से समर्थन नहीं होता था विशाल हैश टेबल, चूंकि एच आमतौर पर एक मशीन शब्द होता है, और एच/लंबाई बढ़ता है, गरीब प्रदर्शन।

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

बेंचमार्क निराशाजनक थे। बेशक, यह कहने की कोई आवश्यकता नहीं है कि शब्दकोश के मुकाबले हमारे कार्यान्वयन पर स्मृति उपयोग बहुत कम था। लेकिन मैं एक अच्छा प्रदर्शन बढ़ावा देने की उम्मीद कर रहा था, लेकिन दुर्भाग्य से यह मामला नहीं था। यह बहुत दूर नहीं था - परिमाण के क्रम से कम - लेकिन दोनों सेटों के लिए और हो जाता है, .NET के कार्यान्वयन ने अभी भी बेहतर प्रदर्शन किया है।

तो मेरा सवाल यह है: क्या हमारे पास सी # के लिए सबसे अच्छा है? मैंने किसी भी कस्टम समाधान की तलाश करने की कोशिश की, और ऐसा लगता है कि लगभग कोई नहीं है। सी 5 जेनेरिक संग्रह है, लेकिन कोड इतनी अव्यवस्थित है कि मैंने परीक्षण भी नहीं किया। और मुझे कोई बेंचमार्क भी नहीं मिला।

तो ... क्या यह है? क्या मुझे बस <> शब्दकोश के आसपास लपेटना चाहिए?

धन्यवाद !!!

+0

शब्दकोश KeyValuePairs को स्टोर नहीं करता है। – SLaks

+3

मैंने अनुभव किया है कि .NET संग्रह * के मैन्युअल पुन: कार्यान्वयन * शामिल कार्यान्वयन के साथ प्रतिस्पर्धा नहीं कर सकते हैं। मुझे नहीं पता कि यह क्यों है लेकिन मुझे संदेह है कि सीएलआर/जेआईटी कोड को अनुकूलित करते समय "धोखा देती है", क्योंकि इसमें .NET कंटेनर का कुछ पूर्व ज्ञान है। –

+1

कोनराड: वास्तव में यह मेरा पसंदीदा जवाब था! :) – Waneck

उत्तर

9

मैं पाया है कि नेट Dictionary ठीक है, नहीं तो असाधारण रूप से अच्छा ज्यादातर स्थितियों में करता है,। यह एक अच्छा सामान्य उद्देश्य कार्यान्वयन है। जिस समस्या में मैं अक्सर दौड़ता हूं वह 2-गीगाबाइट सीमा है। 64-बिट सिस्टम पर, आप किसी शब्दकोश में लगभग 89.5 मिलियन आइटम नहीं जोड़ सकते हैं (जब कुंजी एक पूर्णांक या संदर्भ है, और मान एक संदर्भ है)। शब्दकोश ओवरहेड प्रति आइटम 24 बाइट्स प्रतीत होता है।

वह सीमा स्वयं को एक बहुत ही अजीब तरीके से जाना जाता है। Dictionary दोगुनी होकर बढ़ता प्रतीत होता है - जब यह पूरा हो जाता है, तो यह अगले प्राइम नंबर की क्षमता बढ़ाता है जो कम से कम वर्तमान आकार को दोगुना कर देता है। इसके कारण, शब्दकोश लगभग 47 मिलियन तक बढ़ेगा और फिर अपवाद फेंक देगा क्योंकि जब यह डबल (94 मिलियन तक) करने की कोशिश करता है, तो स्मृति आवंटन विफल रहता है (2 गीगाबाइट सीमा के कारण)। मुझे Dictionary पूर्व-आवंटित करके समस्या के आसपास मिलती है (यानी कन्स्ट्रक्टर को कॉल करें जो आपको क्षमता निर्दिष्ट करने देता है)। यह शब्दकोश को पॉप्युलेट करने में भी गति करता है क्योंकि इसे कभी बढ़ना नहीं पड़ता है, जिसमें एक नई सरणी आवंटित करने और सबकुछ फिर से करने में शामिल होता है।

आप क्या कहना है कि Dictionary टक्कर समाधान के लिए एक लिंक्ड सूची का उपयोग करता है? मुझे पूरा यकीन है कि यह खुले पते का उपयोग करता है, लेकिन मुझे नहीं पता कि यह जांच कैसे करता है। मुझे लगता है कि अगर यह रैखिक जांच करता है, तो प्रभाव एक लिंक की गई सूची के साथ आपको जो मिलता है उसके समान होता है।

हमने 2-गीगाबाइट सीमा को पार करने के लिए अपनी खुद की BigDictionary कक्षा लिखी और पाया कि रैखिक जांच के साथ सीधी खुली एड्रेसिंग योजना उचित रूप से अच्छा प्रदर्शन देती है। यह Dictionary जितना तेज़ नहीं है, लेकिन यह लाखों वस्तुओं (अरबों अगर मुझे स्मृति थी) को संभाल सकता है।

यह कहा गया है कि, एक तेज कार्य-विशिष्ट हैश तालिका लिखने में सक्षम हो जो कुछ स्थितियों में .NET शब्दकोश को बेहतर बनाता है। लेकिन एक सामान्य उद्देश्य हैश टेबल के लिए मुझे लगता है कि बीसीएल द्वारा प्रदान किए जाने वाले कार्यों से बेहतर करने के लिए आपको कठोर दबाव डाला जाएगा।

+0

मैं वास्तव में यह जानकर आश्चर्यचकित हूं कि ओवरहेड प्रति आइटम 24 बाइट्स है !!!! मेरे लिए, यह पहले से ही मेरा हैश संस्करण बनाने का औचित्य साबित करता है, भले ही यह थोड़ा धीमा हो। यदि आप 2 जीबी हैश का उपयोग कर रहे हैं, तो मुझे लगता है कि आपको इससे भी फायदा होगा! – Waneck

+0

मुझे यह भी आश्चर्य है कि कार्यान्वयन प्लेटफ़ॉर्म (यानी कॉम्पैक्ट/माइक्रो फ्रेमवर्क) – Waneck

+0

के अनुसार बदलता है, आप सही हैं, यह वास्तव में एक लिंक्ड सूची का उपयोग नहीं करता है, लेकिन एंट्री स्ट्रक्चर अगले टकराव की सरणी अनुक्रमणिका को संग्रहीत करता है – Waneck

7

"बेहतर" हैश तालिका को desigining में विचार करने के लिए कई चीजें हैं। आपके द्वारा किए गए कस्टम दृष्टिकोणों में से एक कारण धीमा या इससे बेहतर नहीं था।नेट शब्दकोश कि बहुत बार एक हैश तालिका के प्रदर्शन पर बहुत निर्भर है: डेटा टुकड़ों में बांटा जा रहा है

  • हैश समारोह के प्रदर्शन

    • तालिका
    • संख्या का लोड फैक्टर टकराव बनाम गैर-टकराव की
    • टक्कर समाधान के लिए एल्गोरिथ्म
    • तालिका में डेटा की मात्रा और (सूचक/संदर्भ द्वारा या सीधे भीतर बाल्टी) यह कैसे संग्रह किया गया है
    • डेटा
    • सम्मिलन/विलोपन बनाम retrievals
    • एक बंद हैशिंग में आकार बदलने के लिए की जरूरत/खुला को संबोधित कार्यान्वयन
    • और कई अन्य कारकों की संख्या के लिए उपयोग पैटर्न ...

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

    इसलिए, नहीं, .NET शब्दकोश किसी भी विशिष्ट उद्देश्य के लिए अंतिम हैश तालिका नहीं है। लेकिन, शब्दकोश उपयोग की आवृत्ति को देखते हुए, मुझे यकीन है कि माइक्रोसॉफ्ट बीसीएल (बेस क्लास लाइब्रेरी) टीम ने सामान्य मामले के लिए चुने गए दृष्टिकोण को चुनने के लिए बड़ी संख्या में प्रोफाइलिंग की है।

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