स्कूल में असाइनमेंट के लिए मुझे एक साधारण प्रोग्राम बनाने के लिए कहा गया था जो 1000 टेक्स्ट फाइलें बनाता है, प्रत्येक यादृच्छिक राशि के साथ, गिनती है कि बहु-थ्रेड \ एकल प्रक्रिया के माध्यम से कितनी लाइनें हैं। उन फ़ाइलों को हटाने से।मल्टी थ्रेड एक प्रक्रिया से धीमी गति से चलाता है
अब परीक्षण के दौरान एक अजीब चीज होती है - सभी फाइलों की रैखिक गिनती हमेशा एक बहु-थ्रेडेड तरीके से गिनने से थोड़ा तेज होती है जिसने मेरे कक्षा सर्कल के भीतर काफी अकादमिक सिद्धांत सत्र को जन्म दिया है।
जब Scanner
का उपयोग कर सभी फाइलों को पढ़ने के लिए, सब कुछ काम करता है के रूप में इरादा - 1000 फाइलों के आसपास 500ms रैखिक समय में पढ़ रहे हैं और 400 मि.से समय
पिरोया अभी तक जब मैं चारों ओर 110ms रैखिक और 130ms थ्रेड के लिए छोड़ BufferedReader
बार का उपयोग करें।
कोड का कौन सा हिस्सा इस बाधा का कारण बनता है और क्यों?
संपादित करें: बस स्पष्ट करने के लिए, मैं नहीं पूछ रहा हूं कि Scanner
BufferedReader
से धीमा क्यों काम करता है।
पूर्ण संकलन में सक्षम कोड: (हालांकि आप फ़ाइल निर्माण पथ उत्पादन बदलना चाहिए)
import java.io.*;
import java.util.Random;
import java.util.Scanner;
/**
* Builds text files with random amount of lines and counts them with
* one process or multi-threading.
* @author Hazir
*/// CLASS MATALA_4A START:
public class Matala_4A {
/* Finals: */
private static final String MSG = "Hello World";
/* Privates: */
private static int count;
private static Random rand;
/* Private Methods: */ /**
* Increases the random generator.
* @return The new random value.
*/
private static synchronized int getRand() {
return rand.nextInt(1000);
}
/**
* Increments the lines-read counter by a value.
* @param val The amount to be incremented by.
*/
private static synchronized void incrementCount(int val) {
count+=val;
}
/**
* Sets lines-read counter to 0 and Initializes random generator
* by the seed - 123.
*/
private static void Initialize() {
count=0;
rand = new Random(123);
}
/* Public Methods: */ /**
* Creates n files with random amount of lines.
* @param n The amount of files to be created.
* @return String array with all the file paths.
*/
public static String[] createFiles(int n) {
String[] array = new String[n];
for (int i=0; i<n; i++) {
array[i] = String.format("C:\\Files\\File_%d.txt", i+1);
try ( // Try with Resources:
FileWriter fw = new FileWriter(array[i]);
PrintWriter pw = new PrintWriter(fw);
) {
int numLines = getRand();
for (int j=0; j<numLines; j++) pw.println(MSG);
} catch (IOException ex) {
System.err.println(String.format("Failed Writing to file: %s",
array[i]));
}
}
return array;
}
/**
* Deletes all the files who's file paths are specified
* in the fileNames array.
* @param fileNames The files to be deleted.
*/
public static void deleteFiles(String[] fileNames) {
for (String fileName : fileNames) {
File file = new File(fileName);
if (file.exists()) {
file.delete();
}
}
}
/**
* Creates numFiles amount of files.<br>
* Counts how many lines are in all the files via Multi-threading.<br>
* Deletes all the files when finished.
* @param numFiles The amount of files to be created.
*/
public static void countLinesThread(int numFiles) {
Initialize();
/* Create Files */
String[] fileNames = createFiles(numFiles);
Thread[] running = new Thread[numFiles];
int k=0;
long start = System.currentTimeMillis();
/* Start all threads */
for (String fileName : fileNames) {
LineCounter thread = new LineCounter(fileName);
running[k++] = thread;
thread.start();
}
/* Join all threads */
for (Thread thread : running) {
try {
thread.join();
} catch (InterruptedException e) {
// Shouldn't happen.
}
}
long end = System.currentTimeMillis();
System.out.println(String.format("threads time = %d ms, lines = %d",
end-start,count));
/* Delete all files */
deleteFiles(fileNames);
}
@SuppressWarnings("CallToThreadRun")
/**
* Creates numFiles amount of files.<br>
* Counts how many lines are in all the files in one process.<br>
* Deletes all the files when finished.
* @param numFiles The amount of files to be created.
*/
public static void countLinesOneProcess(int numFiles) {
Initialize();
/* Create Files */
String[] fileNames = createFiles(numFiles);
/* Iterate Files*/
long start = System.currentTimeMillis();
LineCounter thread;
for (String fileName : fileNames) {
thread = new LineCounter(fileName);
thread.run(); // same process
}
long end = System.currentTimeMillis();
System.out.println(String.format("linear time = %d ms, lines = %d",
end-start,count));
/* Delete all files */
deleteFiles(fileNames);
}
public static void main(String[] args) {
int num = 1000;
countLinesThread(num);
countLinesOneProcess(num);
}
/**
* Auxiliary class designed to count the amount of lines in a text file.
*/// NESTED CLASS LINECOUNTER START:
private static class LineCounter extends Thread {
/* Privates: */
private String fileName;
/* Constructor: */
private LineCounter(String fileName) {
this.fileName=fileName;
}
/* Methods: */
/**
* Reads a file and counts the amount of lines it has.
*/ @Override
public void run() {
int count=0;
try (// Try with Resources:
FileReader fr = new FileReader(fileName);
//Scanner sc = new Scanner(fr);
BufferedReader br = new BufferedReader(fr);
) {
String str;
for (str=br.readLine(); str!=null; str=br.readLine()) count++;
//for (; sc.hasNext(); sc.nextLine()) count++;
incrementCount(count);
} catch (IOException e) {
System.err.println(String.format("Failed Reading from file: %s",
fileName));
}
}
} // NESTED CLASS LINECOUNTER END;
} // CLASS MATALA_4A END;
@kstandell nay, 'countLinesOneProcess()' बहु-थ्रेडेड नहीं है। यह थ्रेड के '.run()' फ़ंक्शन को '.start()' के बिना कॉल करता है, इसलिए यह केवल नियमित वर्ग विशिष्ट विधि के रूप में चलता है। –
यह जावा नहीं है कि आप जावा बेंचमार्क कैसे करते हैं! ये संख्या पूरी तरह से व्यर्थ हैं। –
क्या एक जटिल होमवर्क – Machado