8

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

एक फ़ाइल के लिए फ़ीचर निष्कर्षण प्रक्रिया एक मानचित्र लौटाती है जिसमें प्रत्येक अद्वितीय सुविधा के लिए फ़ाइल में इसकी घटनाएं होती हैं। मैं सभी फाइलों के मानचित्र (मानचित्र) को एक मानचित्र में विलय करता हूं जिसमें सभी फ़ाइलों से निकाली गई सभी अनूठी विशेषताओं के दस्तावेज़ आवृत्ति (डीएफ) होते हैं। एकीकृत मानचित्र में 10,000,000 से अधिक प्रविष्टियां हो सकती हैं।

वर्तमान में फ़ीचर एक्सट्रैक्शन प्रक्रिया बहुत अच्छी तरह से काम कर रही है और मैं फ़ीचर चयन करना चाहता हूं जिसमें मुझे सूचना लाभ या लाभ अनुपात लागू करने की आवश्यकता है। मुझे पहले मानचित्र को सॉर्ट करना होगा, अंततः एक सूची (प्रत्येक फीचर के लिए, इसके फीचर चयन स्कोर)

मेरा प्रश्न है: सर्वोत्तम अभ्यास और सर्वोत्तम क्या है डेटा संरचना इस बड़ी मात्रा में डेटा (~ 10 एम) पकड़ने और गणना करने के लिए?

+0

हैश मैप पर एक नज़र डालें। – Hungry

उत्तर

1

मेरा अंतर्ज्ञान यह है कि आप प्रारंभिक MapReduce प्रतिमान से प्रेरणा ले सकते हैं और अपनी समस्या को कई छोटे लेकिन समान वाले में विभाजित कर सकते हैं और फिर पूर्ण समाधान तक पहुंचने के लिए इन आंशिक परिणामों को एकत्रित कर सकते हैं।

यदि आप एक समय में एक छोटी समस्या उदाहरण को हल करते हैं (यानी फ़ाइल खंड) यह आपको इस एकल उदाहरण के लिए अंतरिक्ष आवश्यकताओं द्वारा बाध्य एक अंतरिक्ष खपत दंड की गारंटी देगा।

फ़ाइल को आलसी रूप से संसाधित करने के लिए यह दृष्टिकोण आपके द्वारा चुने गए डेटा संरचना का आविष्कार करेगा।

1

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

// here a sample that uses the off-heap memory to back the map 
Map<String, String> map = DBMaker.newMemoryDirectDB().make().getTreeMap("words"); 

//put some stuff into map 
map.put("aa", "bb"); 
map.put("cc", "dd"); 
5

यह एक बहुत ही व्यापक सवाल है, इसलिए उत्तर भी व्यापक हो रहा है। समाधान पर निर्भर करता है (कम से कम) इन तीन चीजों:

  1. अपनी प्रविष्टियां

10.000.000 पूर्णांकों भंडारण स्मृति के 40MiB के बारे में की आवश्यकता होगी के आकार, जबकि 10000000 x 1KiB रिकॉर्ड भंडारण 9GiB से अधिक की आवश्यकता होगी । ये दो अलग-अलग समस्याएं हैं। दस लाख पूर्णांक किसी भी स्टॉक जावा संग्रह में स्मृति में स्टोर करने के लिए तुच्छ हैं, जबकि स्मृति में 9 जीबीबी रखने से आप जावा हीप और कचरा कलेक्टर को ट्विक और ट्यून कर सकते हैं। यदि प्रविष्टियां भी बड़ी हैं, तो 1 एमआईबी कहें, फिर आप पूरी तरह से मेमोरी स्टोरेज को भूल सकते हैं। इसके बजाए, आपको एक अच्छी डिस्क समर्थित डेटा संरचना, शायद एक डेटाबेस खोजने पर ध्यान केंद्रित करने की आवश्यकता होगी।

  1. हार्डवेयर आप

का उपयोग कर रहे राम के 8 GiB के साथ एक मशीन पर एक करोड़ 1KiB रिकॉर्ड भंडारण 128GiB के साथ एक सर्वर पर उन्हें भंडारण के समान नहीं है । चीजें जो पूर्व मशीन के साथ काफी असंभव हैं, बाद वाले के साथ तुच्छ हैं।

  1. गणना (रों) तो TreeMap या शायद PriorityQueue तरह बातें दिमाग में आते हैं आप,

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

क्या आपके कंप्यूटेशंस एक थ्रेड या एकाधिक थ्रेड में चलते हैं? यदि आपके पास अपने डेटा के समवर्ती संशोधन हो सकते हैं, जिसके लिए एक अलग समाधान की आवश्यकता है। ट्रीमैप और प्राथमिकता क्यूयू जैसे डेटा संरचनाओं को या तो ConcurrentLinkedHashMap या ConcurrentSkipListMap जैसे समवर्ती संरचनाओं के साथ लॉक या प्रतिस्थापित किया जाना होगा।