2012-07-31 10 views
6

मैं कोड निम्नलिखित है:जावा समानांतर फ़ाइल प्रसंस्करण

import java.io.*; 
import java.util.concurrent.* ; 
public class Example{ 
public static void main(String args[]) { 
    try { 
     FileOutputStream fos = new FileOutputStream("1.dat"); 
     DataOutputStream dos = new DataOutputStream(fos); 

     for (int i = 0; i < 200000; i++) { 
      dos.writeInt(i); 
     } 
     dos.close();               // Two sample files created 

     FileOutputStream fos1 = new FileOutputStream("2.dat"); 
     DataOutputStream dos1 = new DataOutputStream(fos1); 

     for (int i = 200000; i < 400000; i++) { 
      dos1.writeInt(i); 
     } 
     dos1.close(); 

     Exampless.createArray(200000); //Create a shared array 
     Exampless ex1 = new Exampless("1.dat"); 
     Exampless ex2 = new Exampless("2.dat"); 
     ExecutorService executor = Executors.newFixedThreadPool(2); //Exexuted parallaly to cont number of matches in two file 
     long startTime = System.nanoTime(); 
     long endTime; 
     Future<Integer> future1 = executor.submit(ex1); 
     Future<Integer> future2 = executor.submit(ex2); 
     int count1 = future1.get(); 
     int count2 = future2.get(); 
     endTime = System.nanoTime(); 
     long duration = endTime - startTime; 
     System.out.println("duration with threads:"+duration); 
     executor.shutdown(); 
     System.out.println("Matches: " + (count1 + count2)); 

     startTime = System.nanoTime(); 
     ex1.call(); 
     ex2.call(); 
     endTime = System.nanoTime(); 
     duration = endTime - startTime; 
     System.out.println("duration without threads:"+duration); 

    } catch (Exception e) { 
     System.err.println("Error: " + e.getMessage()); 
    } 
} 
} 

class Exampless implements Callable { 

public static int[] arr = new int[20000]; 
public String _name; 

public Exampless(String name) { 
    this._name = name; 
} 

static void createArray(int z) { 
    for (int i = z; i < z + 20000; i++) { //shared array 
     arr[i - z] = i; 
    } 
} 

public Object call() { 
    try { 
     int cnt = 0; 
     FileInputStream fin = new FileInputStream(_name); 
     DataInputStream din = new DataInputStream(fin);  // read file and calculate number of matches 
     for (int i = 0; i < 20000; i++) { 
      int c = din.readInt(); 
      if (c == arr[i]) { 
       cnt++; 
      } 
     } 
     return cnt ; 
    } catch (Exception e) { 
     System.err.println("Error: " + e.getMessage()); 
    } 
    return -1 ; 
} 

} 

कहाँ मैं दो फ़ाइलों के साथ एक सरणी में मैचों की संख्या गिनती करने के लिए कोशिश कर रहा हूँ। अब, हालांकि मैं इसे दो धागे पर चला रहा हूं, कोड अच्छी तरह से नहीं कर रहा है क्योंकि:

(इसे एकल थ्रेड पर चला रहा है, फ़ाइल 1 + फ़ाइल 2 पढ़ने का समय) < (फ़ाइल 1 || फ़ाइल 2 पढ़ने के समय कई धागे में)।

क्या कोई मुझे यह हल करने में मदद कर सकता है (मेरे पास 2 कोर सीपीयू और फ़ाइल का आकार लगभग 1.5 जीबी है)।

+0

@ सूरजचंद्रन, ज्यादातर बार। और वास्तव में कोई प्रभाव नहीं। :) बस एक परीक्षण चलाओ। – Arpssss

+0

फ़ाइलें 1.5 जीबी नहीं हैं, वे केवल ~ 80 के हैं। –

+0

@ किथरंडल, मैं सिर्फ नमूना उपयोग देता हूं। – Arpssss

उत्तर

7

पहले मामले में आप अनुक्रमिक रूप से एक फ़ाइल, बाइट-बाय-बाइट, ब्लॉक-बाय-ब्लॉक पढ़ रहे हैं। डिस्क I/O जितना तेज़ हो सकता है, फ़ाइल प्रदान करना बहुत खंडित नहीं है। जब आप पहली फ़ाइल के साथ काम करते हैं, डिस्क/ओएस दूसरी फ़ाइल की शुरुआत पाता है और डिस्क के रैखिक पढ़ने के बहुत ही कुशल, जारी रहता है।

दूसरे मामले में आप लगातार पहली और दूसरी फ़ाइल के बीच स्विच कर रहे हैं, डिस्क को एक स्थान से दूसरे स्थान पर ले जाने के लिए मजबूर कर रहे हैं। यह अतिरिक्त मांग समय (लगभग 10 एमएस) आपके भ्रम की जड़ है।

ओह, और आप जानते हैं कि डिस्क एक्सेस एकल-थ्रेडेड है और आपका कार्य I/O बाध्य है इसलिए इस कार्य को एकाधिक थ्रेडों में विभाजित करने का कोई तरीका नहीं है, जब तक कि आप एक ही भौतिक डिस्क से पढ़ रहे हों? आपका दृष्टिकोण केवल उचित हो सकता है अगर:

  • प्रत्येक धागा, एक फ़ाइल से पढ़ने को छोड़कर, भी कुछ सीपीयू गहन प्रदर्शन या मैं/हे की तुलना में संचालन, धीमी अवरुद्ध परिमाण के एक आदेश से किया गया था।

  • फ़ाइलें (अलग विभाजन पर्याप्त नहीं है) या किसी RAID विन्यास पर

  • आप SSD ड्राइव का उपयोग कर रहे

+1

+1। यह एक मौलिक समस्या है कि कई लोग समझ में नहीं आते हैं: केवल सीमित अभिकर्मक को बढ़ाने से प्रदर्शन में वृद्धि होगी। – RedGreasel

1

आप बहु सूत्रण से कोई लाभ नहीं मिलेगा अलग शारीरिक ड्राइव पर हैं चूंकि टॉमस ने डिस्क से डेटा पढ़ने से इंकार कर दिया। यदि आप चेक को मल्टीथ्रेड करते हैं तो आपको गति में कुछ सुधार मिल सकता है, यानी आप फ़ाइलों से डेटा को क्रमशः सरणी में लोड करते हैं और फिर थ्रेड समानांतर में जांच निष्पादित करते हैं। लेकिन आपकी फाइलों के छोटे आकार (~ 80 केबी) पर विचार करना और तथ्य यह है कि आप केवल इनट्स की तुलना कर रहे हैं, मुझे संदेह है कि प्रदर्शन सुधार प्रयास के लायक होगा।

कुछ जो निश्चित रूप से आपकी निष्पादन गति में सुधार करेगा यदि आप readInt() का उपयोग नहीं करते हैं। चूंकि आप जानते हैं कि आप 20000 इनट्स की तुलना कर रहे हैं, आपको 20000 बार पढ़ने के बजाय 20000 बार प्रत्येक फ़ाइल (या कम से कम ब्लॉक में) के लिए सभी सरणी को एक सरणी में पढ़ना चाहिए।