2012-08-08 17 views
21

मेरे पास एक बड़ी फाइल है जो प्रक्रिया के लिए कई घंटे लगती है। तो मैं भाग का अनुमान लगाने और समानांतर में भाग पढ़ने की कोशिश करने के बारे में सोच रहा हूं। क्या एक फ़ाइल पर समवर्ती पढ़ना संभव है? मैंने RandomAccessFile के साथ-साथ nio.FileChannel दोनों को देखा है लेकिन अन्य पोस्टों के आधार पर यह सुनिश्चित नहीं है कि यह दृष्टिकोण काम करेगा या नहीं। सुझाव !!एक फ़ाइल के समवर्ती पढ़ने (जावा preffered)

+0

कौन सा ओएस? जावा या नहीं, विंडोज इस तरह की चीज को अच्छी तरह से संभाल नहीं करता – SJuan76

+0

मैंने कहीं पढ़ा है कि जब यह डिस्कआईओ है, तो आपको समरूपता का लाभ नहीं मिल सकता है। – kosa

+2

डाउनवोट क्यों? मैंने यह सवाल बहुत दिलचस्प पाया। – hectorg87

उत्तर

1

यदि आप हार्ड ड्राइव से फ़ाइल पढ़ रहे हैं, तो डेटा प्राप्त करने का सबसे तेज़ तरीका फ़ाइल को प्रारंभ से अंत तक पढ़ना है, जो कि समवर्ती रूप से नहीं है।

अब यदि यह प्रसंस्करण समय लेता है, तो इससे डेटा के अलग-अलग हिस्सों को संसाधित करने वाले कई धागे होने से लाभ हो सकता है, लेकिन इसका कोई संबंध नहीं है कि आप फ़ाइल को कैसे पढ़ रहे हैं।

+1

मुझे लगता है कि यह सवाल का जवाब नहीं देता है। सवाल यह है: क्या एक बड़ी फाइल के पढ़ने को "समांतर" करना संभव है? – hectorg87

+0

मैं इस धारणा के तहत था कि मौलिक प्रश्न अधिक कहां था "क्या मैं पढ़ने के समानांतर फ़ाइल को जल्दी से पढ़ सकता हूं?" – Buhb

+1

आपके संपादन के बाद: मुझे लगता है कि इसे पढ़ने के साथ करना है क्योंकि यह एक "बड़ी फ़ाइल" है जैसा कि उसने कहा था। बीटीडब्ल्यू, -1 मुझसे नहीं है – hectorg87

7

आप एक बड़ी फ़ाइल पढ़ने के समानांतर कर सकते हैं बशर्ते आपके पास कई स्वतंत्र स्पिंडल हों। जैसे यदि आपके पास RAID 0 + 1 स्ट्रिपेड फ़ाइल सिस्टम है, तो आप एक ही फ़ाइल में एकाधिक समवर्ती पढ़ने को ट्रिगर करके प्रदर्शन सुधार देख सकते हैं।

यदि आपके पास RAID 5 या 6 या सादा एकल डिस्क जैसी संयुक्त फ़ाइल सिस्टम है। यह अत्यधिक संभावना है कि फ़ाइल को क्रमशः पढ़ने से उस डिस्क से पढ़ने का सबसे तेज़ तरीका है। नोट: ओएस पढ़ने के लिए पर्याप्त स्मार्ट है जब यह देखता है कि आप अनुक्रमिक रूप से पढ़ रहे हैं तो ऐसा करने के लिए अतिरिक्त थ्रेड का उपयोग करने में मदद करने की संभावना नहीं है।

यानी एकाधिक धागे का उपयोग करके आप डिस्क को तेज़ी से नहीं बना पाएंगे।

यदि आप डिस्क से तेज़ी से पढ़ना चाहते हैं, तो एक तेज ड्राइव का उपयोग करें। एक सामान्य सैटा एचडीडी लगभग 60 एमबी/सेकेंड पढ़ सकता है और 120 आईओपीएस प्रदर्शन कर सकता है। एक सामान्य सैटा एसएसडी ड्राइव लगभग 400 एमबी/एस पर पढ़ सकती है और 80,000 आईओपीएस कर सकती है और एक सामान्य पीसीआई एसएसडी 900 एमबी/एस पर पढ़ सकता है और 230,000 आईओपीएस प्रदर्शन कर सकता है।

+0

पीटर, समस्या मेरी हार्ड डिस्क पर एक फ़ाइल के साथ है। RAID आदि के लिए मैं फ़ाइल को कैसे विभाजित करूं? – user1132593

+0

RAID स्ट्रिपिंग का उपयोग करते समय स्वचालित रूप से फ़ाइल को विभाजित कर देगा (या RAID 1 यह दो डिस्क पर कॉपी करेगा) RAID 5 और 6 को स्ट्रिपिंग का लाभ मिल सकता है लेकिन यह आपके नियंत्रक पर निर्भर करता है क्योंकि इन्हें अक्सर अधिकतम थ्रूपुट यानी अनुक्रमिक पढ़ने के लिए अनुकूलित किया जाता है । –

+1

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

1

आप समानांतर में संसाधित कर सकते हैं, हालांकि आपकी हार्ड ड्राइव एक समय में डेटा का एक टुकड़ा पढ़ सकती है। यदि आप एक थ्रेड के साथ फ़ाइल में पढ़ते हैं, तो आप डेटा को कई धागे से संसाधित कर सकते हैं।

15

सबसे महत्वपूर्ण सवाल यहां है आपके मामले में में बाधा क्या है।

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

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

import java.io.*; 
import java.util.*; 
import java.util.concurrent.*; 

public class Split { 
    private File file; 

    public Split(File file) { 
     this.file = file; 
    } 

    // Processes the given portion of the file. 
    // Called simultaneously from several threads. 
    // Use your custom return type as needed, I used String just to give an example. 
    public String processPart(long start, long end) 
     throws Exception 
    { 
     InputStream is = new FileInputStream(file); 
     is.skip(start); 
     // do a computation using the input stream, 
     // checking that we don't read more than (end-start) bytes 
     System.out.println("Computing the part from " + start + " to " + end); 
     Thread.sleep(1000); 
     System.out.println("Finished the part from " + start + " to " + end); 

     is.close(); 
     return "Some result"; 
    } 

    // Creates a task that will process the given portion of the file, 
    // when executed. 
    public Callable<String> processPartTask(final long start, final long end) { 
     return new Callable<String>() { 
      public String call() 
       throws Exception 
      { 
       return processPart(start, end); 
      } 
     }; 
    } 

    // Splits the computation into chunks of the given size, 
    // creates appropriate tasks and runs them using a 
    // given number of threads. 
    public void processAll(int noOfThreads, int chunkSize) 
     throws Exception 
    { 
     int count = (int)((file.length() + chunkSize - 1)/chunkSize); 
     java.util.List<Callable<String>> tasks = new ArrayList<Callable<String>>(count); 
     for(int i = 0; i < count; i++) 
      tasks.add(processPartTask(i * chunkSize, Math.min(file.length(), (i+1) * chunkSize))); 
     ExecutorService es = Executors.newFixedThreadPool(noOfThreads); 

     java.util.List<Future<String>> results = es.invokeAll(tasks); 
     es.shutdown(); 

     // use the results for something 
     for(Future<String> result : results) 
      System.out.println(result.get()); 
    } 

    public static void main(String argv[]) 
     throws Exception 
    { 
     Split s = new Split(new File(argv[0])); 
     s.processAll(8, 1000); 
    } 
} 
+0

धन्यवाद पेट्र, मेरे पास कुछ समान है लेकिन रननेबल्स (पुराना तरीका) का उपयोग कर रहा था। मेरा अवलोकन था कि केवल एक धागा व्यस्त था और इसलिए मैंने यह सवाल क्यों पोस्ट किया। मैं जल्द ही पुनः प्रयास करूंगा और अपने अवलोकनों को वापस पोस्ट करूंगा – user1132593

+2

मैं फ़ाइल को तोड़ने और इसे समवर्ती रूप से पढ़ने में सक्षम था। के लिए ।यहां 5 जीबी पाठ फ़ाइल मेरे परिणाम थे (hh.mm.ss.SSS): भाग = [1]: 0: 18: 10.328 भाग = [2]: 0: 13: 1 9 .125 भाग = [3]: 0: 12: 54.824 । एक अंतर नहीं है। हालांकि मेरे लिए सबसे अच्छा समाधान फ़ाइल को ज़िप करना था और ज़िप फ़ाइल को क्रमशः संसाधित करना था। यह उच्च संपीड़न अनुपात की वजह से था। ज़िप फ़ाइल 10 एमबी हो गई – user1132593

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