में समानांतर में एक फ़ाइल के सभी लाइनों को पढ़ने के लिए मैं एक Stream<String>
में तेजी से संभव के रूप में के रूप में एक 1 जीबी बड़ी फाइल के सभी लाइनों पढ़ना चाहते हैं। वर्तमान में मैं इसके लिए Files(path).lines()
का उपयोग कर रहा हूं। फ़ाइल को पार्स करने के बाद, मैं कुछ कंप्यूटेशंस कर रहा हूं (map()
/filter()
) पहले मैंने सोचा कि यह पहले से ही समानांतर में किया गया है, लेकिन ऐसा लगता है कि मैं गलत हूं: फ़ाइल को पढ़ने के दौरान, इसमें लगभग 50 सेकंड लगते हैं मेरे दोहरी सीपीयू लैपटॉप पर। हालांकि, अगर मैं बैश कमांड का उपयोग कर फ़ाइल को विभाजित करता हूं और फिर उन्हें समानांतर में संसाधित करता हूं, तो इसमें केवल 30 सेकंड लगते हैं।कैसे जावा 8
मैं निम्नलिखित संयोजनों की कोशिश की:
- एकल फाइल, कोई समानांतर रेखाओं() धारा ~ 50 सेकंड
- एकल फाइल,
Files(..).lines().parallel().[...]
~ 50 सेकंड - दो फ़ाइलों, कोई समानांतर रेखाओं() strean इन ~ 30 सेकंड
- दो फ़ाइलों,
Files(..).lines().parallel().[...]
~ 30 सेकंड
मैं भाग गया मोटे तौर पर एक ही परिणाम के साथ 4 एकाधिक बार (1 या 2 सेकंड तक)। [...]
मूल्यांकन को ट्रिगर करने के लिए अंत में toArray(...)
के साथ मानचित्र और फ़िल्टर की एक श्रृंखला है।
निष्कर्ष यह है कि lines().parallel()
का उपयोग करने में कोई अंतर नहीं है। समानांतर में दो फ़ाइलों को पढ़ने के रूप में एक छोटा सा समय लगता है, फ़ाइल को विभाजित करने से प्रदर्शन लाभ होता है। हालांकि ऐसा लगता है कि पूरी फाइल क्रमशः पढ़ी जाती है।
संपादित करें: मुझे लगता है कि मैं एक एसएसडी का उपयोग कहना चाहते हैं, इसलिए वहाँ समय की मांग करने के लिए व्यावहारिक रूप से है। फ़ाइल में कुल 1658652 (अपेक्षाकृत छोटी) रेखाएं हैं। विभाजन बैश में फाइल के बारे में 1.5 सेकंड लेता है: time split -l 829326 file # 829326 = 1658652/2 split -l 829326 file 0,14s user 1,41s system 16% cpu 9,560 total
तो मेरे सवाल है, वहाँ किसी भी वर्ग या जावा 8 JDK जो यह पहली बार विभाजित करने के लिए बिना सभी लाइनों को पढ़ने parallelize सकते में समारोह है? उदाहरण के लिए, अगर मैं दो सीपीयू कोर है, पहली पंक्ति पाठक पहली पंक्ति और लाइन (totalLines/2)+1
पर एक दूसरे से एक पर शुरू कर देना चाहिए।
क्या मतलब है _ bash_ का उपयोग कर फ़ाइल को संपादित करें? साथ ही, आपको लाइनों को खोजने के लिए फ़ाइल को पढ़ना होगा। यह सिर्फ यह नहीं पता कि लाइन टर्मिनेटर कहां हैं। –
@SotiriosDelimanolis आप फ़ाइल में एक मनमाना बिंदु पर जाने और पहले नई लाइन के लिए देखो और पहले पूरे क्षेत्र में सभी डेटा प्रसंस्करण के बिना इस तरह से विभाजित कर सकते हैं। –
बैश में, आप 'split -l # लाइन'' का उपयोग कर सकते हैं, इसे 'wc -l' के साथ दो हिस्सों में विभाजित करने के लिए गठबंधन करें। माइकल Petch मेरा विचार :) – user3001