2008-12-18 22 views
9

मेरे पास Dictionary<string,int> है जिसमें 10+ मिलियन अद्वितीय कुंजी के ऊपर होने की क्षमता है। मैं अभी भी शब्दकोश की कार्यक्षमता को बनाए रखते हुए, स्मृति की मात्रा को कम करने की कोशिश कर रहा हूं।सी # शब्दकोश मेमोरी प्रबंधन

मैं के रूप में एक लंबे बजाय तार का एक हैश भंडारण का विचार था, इस (~ 1.5 गिग ~ .5 गिग करने के लिए) एक स्वीकार्य राशि के लिए क्षुधा स्मृति उपयोग कम हो जाती है, लेकिन मैं के बारे में बहुत अच्छा नहीं लग रहा है ऐसा करने के लिए मेरी विधि।

long longKey= 
BitConverter.ToInt64(cryptoTransformSHA1.ComputeHash(enc.GetBytes(strKey)), 0); 

मूल रूप से यह एक SHA1 हैश के अंत कांट-छांट कर, और एक लंबे, जो मैं तो एक प्रमुख के रूप में उपयोग में की पहली हिस्सा डालता है। हालांकि यह काम करता है, कम से कम उस डेटा के लिए जिसके साथ मैं परीक्षण कर रहा हूं, मुझे ऐसा नहीं लगता कि यह महत्वपूर्ण टकरावों की बढ़ती संभावना के कारण एक बहुत ही विश्वसनीय समाधान है।

क्या डिक्शनरी की मेमोरी पदचिह्न को कम करने के कोई अन्य तरीके हैं, या क्या मेरे ऊपर की विधि उतनी ही भयानक नहीं है जितनी मुझे लगता है?

[संपादित करें] स्पष्टीकरण के लिए, मुझे स्ट्रिंग का उपयोग करके शब्दकोश में निहित मान को देखने की क्षमता को बनाए रखने की आवश्यकता है। शब्दकोश में वास्तविक स्ट्रिंग को संग्रहीत करना बहुत मेमोरी तक जाता है। इसके बजाय मैं Dictionary<long,int> का उपयोग करना चाहता हूं जहां स्ट्रिंग पर हैशिंग फ़ंक्शन का परिणाम लंबा है।

+1

शब्दकोश ? – Diadistis

+1

मुझे संदेह है कि टकराव की संभावना 64-बिट हैश के साथ यथार्थवादी है। –

+0

मैं कल्पना करता हूं कि यह मामला भी हो, लेकिन आधे में बाइट्स को 'चॉपिंग' करना थोड़े iffy लगता है। –

उत्तर

11

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

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

64 बिट हैश के लिए मैं वर्तमान में लुकअप 3 और एफएनवी 1 का उपयोग करता हूं, जो 32 बिट हैंश दोनों हैं। एक टकराव के लिए दोनों को टकराव की आवश्यकता होगी जो गणितीय रूप से असंभव है और मैंने लगभग 100 मिलियन से अधिक हैश नहीं देखा है। आप वेब पर सार्वजनिक रूप से उपलब्ध दोनों कोड को पा सकते हैं।

अभी भी अपना खुद का विश्लेषण करें। मेरे लिए क्या काम किया है आपके लिए काम नहीं कर सकता है। असल में मेरे कार्यालय के अंदर विभिन्न आवश्यकताओं के साथ विभिन्न अनुप्रयोग वास्तव में विभिन्न हैश कार्यों या हैश कार्यों के संयोजन का उपयोग करते हैं।

मैं किसी भी असुरक्षित हैश फ़ंक्शंस से बचूंगा। ऐसे लोगों के रूप में कई हैश फ़ंक्शन हैं जो सोचते हैं कि उन्हें उन्हें लिखना चाहिए। अपना शोध और परीक्षण परीक्षा परीक्षण करें।

+0

मैंने आपके 64 बिट हैश विचार का एक संस्करण लागू किया, और प्रारंभिक परीक्षण अच्छी तरह से चला गया। मैं कुछ और परीक्षण करने जा रहा हूं, लेकिन यह ऐसे समाधान की तरह दिखता है जो मेरे उद्देश्यों के लिए मेमोरी आकार और एक्सेस समय के बीच सबसे अच्छा व्यापार है। – blogsdon

+0

कूल। मुझे 64 बिट हैश तकनीक पसंद है। आपने किस हश फ़ंक्शन का उपयोग किया था? वास्तव में प्रश्न का उत्तर देने के लिए –

+0

+1 और संबंधपरक डेटाबेस की अनुशंसा करने की कोशिश नहीं कर रहा है। –

3

स्ट्रिंग के हैश प्राप्त करने के लिए आप GetHashCode() का उपयोग क्यों नहीं करते हैं?

+0

GetHashCode() बिल्कुल विश्वसनीय नहीं है ... – Diadistis

+0

मैंने पहले कोशिश की, लेकिन यह टकराव का कारण बन गया। – blogsdon

+0

मुझे पता नहीं था कि GetHashCode विश्वसनीय नहीं था - अधिक जानकारी? –

2

हैशटेबल कार्यान्वयन के साथ मैंने अतीत में काम किया है, हैश आपको एक बाल्टी में लाता है जो प्रायः अन्य वस्तुओं की एक लिंक सूची होती है जिसमें एक ही हैश होता है। हैश अद्वितीय नहीं हैं, लेकिन वे आपके डेटा को बहुत ही प्रबंधनीय सूचियों (कभी-कभी केवल 2 या 3 लंबे) में विभाजित करने के लिए पर्याप्त हैं, फिर आप अपनी वास्तविक वस्तु को खोजने के लिए खोज सकते हैं।

एक अच्छी हैश की कुंजी इसकी विशिष्टता नहीं है, लेकिन इसकी गति और वितरण क्षमताओं ... आप इसे जितना संभव हो उतना वितरित करना चाहते हैं।

+0

शब्दकोश इस तरह से काम नहीं करता है। यह प्रमुख टकराव की अनुमति नहीं देगा। आपको एक अलग डेटा संरचना का उपयोग करना होगा और टकराव को संभालने के लिए आपको हश की कुंजी और असली कुंजी दोनों को स्टोर करने की आवश्यकता होगी - जब तक कि आप जो मूल्य खोज रहे हैं उसे भी नहीं जानते। यह किसी भी स्मृति को बचा नहीं होगा। – tvanfosson

+0

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

5

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

/संपादित करें: जैसा कि एंड्रयू ने नोट किया है, इस समस्या के समाधान के बाद से इसका समाधान है। और एक सच्चे शब्दकोश की तरह, आपको टकराव के आसपास काम करना होगा। इसके लिए सबसे अच्छी योजनाओं में से एक double hashing है। दुर्भाग्य से, वास्तव में मूल मूल्यों को संग्रहीत करने के लिए केवल 100% विश्वसनीय तरीका होगा। अन्यथा, आपने एक अनंत संपीड़न बनाया होगा, जिसे हम जानते हैं कि अस्तित्व में नहीं है।

+0

असल में वह _is_ वह क्या कर रहा है। डिक्ट के बदले इसके डिक्ट और कुंजी मूल स्ट्रिंग का क्रिप्टोश है, जबकि string.gethashcode से पहले संरेखण नमूने में डुप्लिकेट कुंजी पैदा कर रहा था। –

+0

निकोलस, आप सही हैं - लेकिन एक (अपंग) क्रेटो हैश * अभी भी एक बुरा हैश है, भले ही डबल हैशिंग में उपयोग किया जाता है। –

+0

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

7

10 मिलियन-अजीब रिकॉर्ड के साथ, क्या आपने गैर-क्लस्टर इंडेक्स वाले डेटाबेस का उपयोग करने पर विचार किया है? इस प्रकार की चीज़ के लिए डेटाबेस में अपनी आस्तीन बहुत अधिक चाल है।

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

तारों का उपयोग अंतरिक्ष ले सकता है, लेकिन यह विश्वसनीय है ...यदि आप x64 पर हैं तो यह बहुत बड़ा नहीं होना चाहिए (हालांकि) यह निश्चित रूप से "बड़ा" के रूप में गिना जाता है ;-p)

2

बस SQLite प्राप्त करें। आपको इसे हरा करने की संभावना नहीं है, और यदि आप ऐसा करते हैं, तो शायद यह समय/प्रयास/जटिलता के लायक नहीं होगा।

SQLite।

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