2008-09-17 18 views
6

तो मेरे पास संख्यात्मक डेटा (गीगाबाइट्स पूरी तरह से) की "बहुत बड़ी" ASCII फ़ाइलों की "बड़ी" संख्या है, और मेरे कार्यक्रम को कम से कम एक बार अनुक्रमिक रूप से इसकी पूरी प्रक्रिया को संसाधित करने की आवश्यकता होगी।बड़े डेटा वॉल्यूम्स को संभालने पर सलाह

डेटा संग्रहित/लोड करने पर कोई सलाह? मैंने फ़ाइलों को छोटे बनाने और तेज़ी से लोड करने के लिए बाइनरी में कनवर्ट करने का विचार किया है।

क्या मुझे सब कुछ एक ही समय में स्मृति में लोड करना चाहिए?
यदि नहीं, तो डेटा को आंशिक रूप से लोड करने का एक अच्छा तरीका क्या खोल रहा है?
कुछ जावा-प्रासंगिक दक्षता युक्तियाँ क्या हैं?

+2

@ जेक: मैंने टेक्स्ट फाइलों के जावा एप्लिकेशन प्रसंस्करण गीगाबाइट्स (ASCII, UTF-8 और UTF-16 {be, le} दोनों) लिखा था। * * जिस चीज ने अंतर बनाया: निर्माता/उपभोक्ता योजना में स्विच करना और कई कोरों पर लोड फैलाना (मशीन को अपनाना)। हमारे पास एक धागा आई/ओ कर रहा है, जो उपभोग करने के लिए "भाग" का उत्पादन करता है। तब हमारे पास डेटा को संसाधित करने के समानांतर में काम करने वाले कई धागे हैं। 16-कोर मशीन पर एक सीपीयू मॉनीटर का उपयोग करके काम पर देखना आश्चर्यजनक है :) तो मूल रूप से आपको यह पता लगाना होगा कि आप कहां बाध्य हैं: क्या आप I/O बाध्य हैं या CPU बाध्य हैं? यदि आप सीपीयू बाध्य हैं, तो मेरी टिप समानांतर है। – SyntaxT3rr0r

उत्तर

6

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

मैं के एक बड़े प्रशंसक 'स्मृति मैप की आई/ओ' कर रहा हूँ, उर्फ ​​'प्रत्यक्ष बाइट बफ़र्स'। जावा में उन्हें Mapped Byte Buffers कहा जाता है java.nio का हिस्सा हैं। (असल में, यह तंत्र ओएस की वर्चुअल मेमोरी पेजिंग सिस्टम का उपयोग आपकी फाइलों को 'मैप' करने के लिए करता है और उन्हें प्रोग्रामेटिक रूप से बाइट बफर के रूप में पेश करता है। ओएस बाइट्स को डिस्क से और मेमोरी ऑटो-जादुई और बहुत तेज़ी से ले जाने का प्रबंधन करेगा।

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

आप अपने संदर्भ में एमबीबी का उपयोग कैसे करेंगे? बस अपनी प्रत्येक फाइल के लिए एमबीबी बनाएं और फिट बैठे हुए उन्हें पढ़ें। आपको केवल अपने परिणामों को स्टोर करने की आवश्यकता होगी। ।

बीटीडब्ल्यू: जीबी में आप कितना डेटा से निपट रहे हैं?यदि यह 3-4 जीबी से अधिक है, तो यह 32-बिट मशीन पर आपके लिए काम नहीं करेगा क्योंकि एमबीबी कार्यान्वयन प्लेटफार्म आर्किटेक्चर द्वारा एड्रेस करने योग्य मेमोरी स्पेस पर प्रतिवादी है। एक 64-बिट मशीन & ओएस आपको मैपटेबल डेटा के 1TB या 128TB पर ले जाएगा।

आप प्रदर्शन के बारे में सोच रहे हैं, तो किर्क Pepperdine पता वह एक वेबसाइट, www.JavaPerformanceTuning.com, कुछ और MBB विवरण होता है कि उस के साथ शामिल है (कुछ हद तक एक प्रसिद्ध जावा प्रदर्शन गुरु।): NIO Performance Tips और अन्य जावा प्रदर्शन संबंधित चीजें।

0

आपने वास्तव में हमें आपकी सहायता करने के लिए पर्याप्त जानकारी नहीं दी है। क्या आपको इसे संसाधित करने के लिए पूरी तरह से प्रत्येक फ़ाइल को लोड करने की आवश्यकता है? या आप लाइन से लाइन को संसाधित कर सकते हैं?

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

+0

हाँ, मैं पूरी तरह से एक बफर का उपयोग कर सकते हैं और उपयोग करना चाहिए। तो फिर क्या होगा यदि प्रसंस्करण के लिए एकाधिक फ़ाइलों और एकाधिक बफर के लिए डेटा में चारों ओर कूदना आवश्यक है? क्या लगातार खुलने और द्विआधारी फाइलों का बंद होना महंगा हो रहा है? – Jake

0

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

मुझे लगता है कि आप यहां प्रसंस्करण के परिणामों के साथ कुछ करना चाहते हैं, जैसे इसे कहीं स्टोर करें।

0

यदि आपका संख्यात्मक डेटा नियमित रूप से नमूना लिया जाता है और आपको उन्हें quadtree में संग्रहीत करने के लिए यादृच्छिक पहुंच करने की आवश्यकता होती है।

1

आप बाइनरी में परिवर्तित कर सकते हैं, लेकिन फिर आपके पास मूल की स्थिति रखने की आवश्यकता है, तो डेटा की 1+ प्रतियां हैं।

अपने मूल एसीआईआई डेटा के शीर्ष पर किसी प्रकार की अनुक्रमणिका बनाने के लिए व्यावहारिक हो सकता है, ताकि यदि आपको डेटा फिर से जाने की आवश्यकता हो तो आप इसे बाद में तेजी से कर सकते हैं।

क्रम में आपके सवालों के जवाब के लिए:

मैं सभी को एक बार स्मृति में सब कुछ लोड करना चाहिए?

यदि ऐसा नहीं है तो नहीं। कुछ फाइलों के लिए, आप सक्षम हो सकते हैं, लेकिन यदि आप अनुक्रमिक रूप से प्रसंस्करण कर रहे हैं, तो बस कुछ भी एक-एक करके चीजों के माध्यम से पढ़ा जाए, जो आपको जिस तरह से चाहिए उसे संग्रहीत करें।

यदि नहीं, तो डेटा को आंशिक रूप से लोड करने का एक अच्छा तरीका क्या खोल रहा है?

बुफर्ड रीडर/आदि सबसे आसान है, हालांकि आप एक समय में डेटा की खिड़कियों के माध्यम से जाने के लिए मेमोरीमैप I/O का उपयोग करने के लिए FileChannel/etc में गहराई से देख सकते हैं।

कुछ जावा-प्रासंगिक दक्षता युक्तियाँ क्या हैं?

यह वास्तव में इस बात पर निर्भर करता है कि आप डेटा के साथ क्या कर रहे हैं!

1

किस प्रकार की प्रसंस्करण चल रही है, इस बारे में कोई अतिरिक्त अंतर्दृष्टि के बिना, यहां कुछ सामान्य विचार हैं जब मैंने समान कार्य किया है।

  1. अपने एप्लिकेशन का एक प्रोटोटाइप लिखें (शायद यहां तक ​​कि "फेंकने वाला" भी) जो आपके डेटा सेट पर कुछ मनमाने ढंग से संचालन करता है। देखें कि यह कितनी तेजी से चला जाता है। यदि सबसे सरल, सबसे बेवकूफ चीज जिसे आप सोच सकते हैं वह स्वीकार्य रूप से तेज़ है, कोई चिंता नहीं!

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

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

"सबकुछ स्मृति में लोड न करें" न करें। बस फ़ाइल का उपयोग करें और ऑपरेटिंग सिस्टम के डिस्क पेज कैश को यह तय करने दें कि जब आप वास्तव में चीजों को सीधे स्मृति से बाहर खींचते हैं।

+0

@ 2: नहीं, मुझे अनिवार्य रूप से डेटा की एक विंडो (सभी फ़ाइलों के लिए) के लिए यादृच्छिक पहुंच प्रदान करने की आवश्यकता है। – Jake

0

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

2

आप Wide Finder Project में प्रविष्टियों को देखना चाहते हैं ("wide finder" java के लिए Google खोज करें)।

वाइड खोजक में लॉग फ़ाइलों में बहुत सी रेखाएं पढ़ने में शामिल है, इसलिए जावा कार्यान्वयन देखें और देखें कि क्या काम करता है और वहां काम नहीं करता है।

0

यदि संभव हो, तो डेटा को डेटाबेस में प्राप्त करें। फिर आप वहां मौजूद सभी इंडेक्सिंग, कैशिंग, मेमोरी पिनिंग और अन्य कार्यक्षमता का लाभ उठा सकते हैं।

1

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

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

0

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

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