2008-10-21 16 views
6

हमारे डेस्कटॉप एप्लिकेशन में, हमने inverted index का उपयोग करके एक सरल खोज इंजन लागू किया है।आवेदन के लिए इन-मेमोरी सर्च इंडेक्स बहुत अधिक मेमोरी लेता है - कोई सुझाव?

दुर्भाग्यवश, हमारे कुछ उपयोगकर्ता डेटासेट बहुत बड़े हो सकते हैं, उदा। उलटा इंडेक्स बनने से पहले ~ 1 जीबी मेमोरी लेना। उलटा इंडेक्स स्वयं बहुत मेमोरी लेता है, जितना डेटा अनुक्रमित होता है (एक और 1 जीबी रैम)।

स्पष्ट रूप से यह स्मृति त्रुटियों के साथ समस्याएं पैदा करता है, क्योंकि 32 बिट विंडोज़ प्रति 2 जीबी मेमोरी प्रति सेकंड की सीमा है, या कम स्पेस कंप्यूटर वाले उपयोगकर्ता स्मृति मांग से निपटने के लिए संघर्ष करते हैं।

हमारे औंधा सूचकांक एक के रूप में संग्रहीत किया जाता है:

Dictionary<string, List<ApplicationObject>> 

और यह बनाई गई है डेटा लोड होने के दौरान जब प्रत्येक वस्तु के इस तरह संसाधित किया जाता है कि applicationObject के प्रमुख स्ट्रिंग और विवरण शब्द उल्टे सूचकांक में जमा हो जाती है।

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

उत्तर

3

यदि यह 1 जीबी होने जा रहा है ... इसे डिस्क पर रखें। बर्कले डीबी जैसे कुछ का प्रयोग करें। यह अभी भी बहुत तेज होगा।

यहाँ एक परियोजना है कि यह करने के लिए एक .net इंटरफेस प्रदान करता है है:

http://sourceforge.net/projects/libdb-dotnet

+0

यदि संभव हो तो मैं इसे टालना चाहूंगा, क्योंकि इन-मेमोरी सर्च इंडेक्स होना आसान होगा। लेकिन शायद यह संभव नहीं है, लेकिन ऐसा लगता है कि * मुझे * संभव होना चाहिए। – RickL

1

मैं bobwienholt से सहमत हैं, लेकिन आप डेटासेट का अनुक्रमण रहे हैं, तो मैं इन कहीं एक डेटाबेस से आया मान। क्या यह खोजने के लिए समझ में आता है कि DTSearch या Lucene.net जैसे खोज इंजन के साथ?

+0

शायद, लेकिन मुझे लगता है कि यह अधिक जटिल होगा? यानी एप्लिकेशन ऑब्जेक्ट कई अलग-अलग तालिकाओं में संग्रहीत हैं जो विभिन्न विशिष्ट अनुप्रयोग ऑब्जेक्ट्स को मैप करते हैं। आह, हमारे आवेदन को भी buffered किया गया है ताकि इन-मेमोरी डेटासेट डेटाबेस के साथ सिंक हो सके। – RickL

3

मैं कुछ समाधान देखें:

  1. आप एक सरणी में ApplicationObjects है, तो दुकान बस सूचकांक - छोटे हो सकता है।
  2. यूटीएफ -8 का उपयोग करके, आप शब्दकोश को स्टोर करने के लिए थोड़ा सी ++/सीएलआई का उपयोग कर सकते हैं।
  3. सभी विभिन्न तार भंडारण परेशान न हों, एक Trie
+0

बिंदु 1 के लिए) वे एक सरणी में संग्रहीत नहीं हैं, लेकिन क्या आपका मतलब स्ट्रिंग कुंजी के बजाय इंडेक्स को स्टोर करना है? फिर आप तारों से कैसे खोज करते हैं? या सूची की सूची सूची के बजाय आपका मतलब था? मुझे लगता है कि यह छोटा हो सकता है, लेकिन शायद एक बड़ी राशि नहीं है। – RickL

3

का उपयोग मैं आप पा सकते हैं आप बहुत छोटी सूचियों का एक बहुत मिल गया है संदेह है।

मेरा सुझाव है कि आप मोटे तौर पर आवृत्ति की तरह पता लगाते हैं - आपकी कितनी शब्दकोश प्रविष्टियों में एकल तत्व सूचियां हैं, कितने तत्वों की सूची है। आप संभावित रूप से कई अलग-अलग शब्दकोशों को स्टोर कर सकते हैं - एक के लिए "मैं केवल तब तक एक तत्व मिला "(प्रत्यक्ष मैपिंग)" मेरे पास दो तत्व हैं "(दो संदर्भों के साथ एक जोड़ी संरचना में मानचित्र) आदि जब तक यह मूर्खतापूर्ण न हो जाए - संभवतः लगभग 3 प्रविष्टियों में - जिस बिंदु पर आप सामान्य पर वापस जाते हैं सूचियों। एक साधारण इंटरफ़ेस के पीछे पूरी तरह से Encapsulate (प्रवेश प्रविष्टि/प्रविष्टियों को पुनः प्राप्त करें)। इस तरह आपके पास बहुत कम बर्बाद जगह होगी (ज्यादातर खाली बफर, मायने रखता है आदि)।

यदि इनमें से कोई भी बहुत समझ में नहीं आता है, तो मुझे बताएं और मैं कुछ कोड के साथ आने का प्रयास करूंगा।

+0

यह एक दिलचस्प अवलोकन है ... हाँ, मुझे लगता है कि अधिकांश सूचियां बहुत छोटी होंगी। आपके सुझाव के साथ, मुझे लगता है कि उलटा इंडेक्स निर्माण में अधिक समय लगेगा क्योंकि आपको 1-आइटम, 2-आइटम, आदि शब्दकोशों के बीच वस्तुओं को स्थानांतरित करना होगा, लेकिन संभावित रूप से अंतरिक्ष को बचा सकता है। – RickL

+0

मुझे संदेह है कि प्रदर्शन में अंतर बहुत छोटा होगा, ईमानदार होने के लिए - लेकिन हाँ, कुछ ओवरहेड होगा। हालांकि इसे कोडिंग करने से पहले वितरण की जांच करने के लिए निश्चित रूप से मूल्यवान है :) –

+0

एक व्यक्ति ने इसे शुरू करने के लिए संभावित रूप से सस्ता बनाने का विचार किया: बस एक एकल शब्दकोश > है। इसका अर्थ यह है कि इससे बचने के लिए structs का उपयोग करने के बजाय प्रति वस्तु ऑब्जेक्ट रखना है, लेकिन आपको केवल –

0

क्या इंडेक्स केवल इसमें जोड़ा गया है या आप इसे से भी हटाते हैं?

+0

संदर्भित अनुप्रयोग ऑब्जेक्ट को हटाए जाने पर कुंजी को इंडेक्स से हटा दिया जाना चाहिए। – RickL

1

आप ल्यूसीन के दृष्टिकोण को ले सकते हैं। सबसे पहले, आप यादृच्छिक एक्सेस इन-मेमोरी स्ट्रीम (System.IO.MemoryStream) बनाते हैं, यह स्ट्रीम ऑन-डिस्क एक को मिरर करती है, लेकिन इसका केवल एक हिस्सा (यदि आपके पास गलत हिस्सा है, तो डिस्क से दूसरे को लोड करें) । इससे एक सिरदर्द होता है, आपको अपने शब्दकोश के लिए फ़ाइल-मैप करने योग्य प्रारूप की आवश्यकता होती है। विकिपीडिया में paging technique का विवरण है।

फ़ाइल-मैप्पेबल परिदृश्य पर। यदि आप परावर्तक खोलते हैं और डिक्शनरी क्लास को प्रतिबिंबित करते हैं तो आप देखेंगे कि बाल्टी शामिल है। आप शायद इन बाल्टीओं में से प्रत्येक पृष्ठ और भौतिक फ़ाइल के रूप में उपयोग कर सकते हैं (इस तरह आवेषण तेजी से होते हैं)। फिर आप फ़ाइल में "आइटम x हटाए गए" मान को डालने से मूल्यों को भी कम कर सकते हैं और प्रत्येक फ़ाइल को अक्सर साफ़ कर देता है।

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

1

आपकी मेमोरी संरचना को पारदर्शी रूप से वापस करने के लिए मेमोरी मैप किए गए फ़ाइल Win32 API का उपयोग करने के बारे में कैसे?

http://www.eggheadcafe.com/articles/20050116.asp में इसे सक्षम करने के लिए आवश्यक PInvokes है।

+1

.NET Framework संस्करण 4 से प्रारंभ करने के बाद, आप एमएसडीएन लाइब्रेरी में Win32 में मेमोरी-मैप की गई फ़ाइलों को प्रबंधित करने में वर्णित मेमोरी-मैप की गई फ़ाइलों तक पहुंचने के लिए मेमोरी-मैप की गई फ़ाइलों तक पहुंचने के लिए प्रबंधित कोड का उपयोग कर सकते हैं। http://msdn.microsoft.com/en-us/library/dd997372.aspx – Tony

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

  • कोई संबंधित समस्या नहीं^_^