Почему мой многопоточный ввод-вывод Java медленнее последовательного?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Почему мой многопоточный ввод-вывод Java медленнее последовательного?

Сообщение Anonymous »

При тестировании создания потоков/параллельной обработки я столкнулся со странной ситуацией, когда многопоточный код работает намного медленнее, чем последовательная версия.
Код такой: просто подсчитывает слова в файлах, а затем суммирует результат.
Последовательный код:

Код: Выделить всё

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;

public class WordCount {

public static int countWords(String filename) throws IOException {
long startTime = System.currentTimeMillis();
try (BufferedReader br = new BufferedReader(new FileReader(filename))) {
int total = 0;
for (String line = br.readLine(); line != null; line = br.readLine()) {
total += line.split("\\s+").length;
}
System.out.println("Time for file "+filename+" : "+(System.currentTimeMillis()-startTime) + " ms for "+ total + " words");
return total;
}
}

public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int [] wordCount = new int[args.length];
for (int i = 0; i < args.length; i++) {
try {
wordCount[i] = countWords(args[i]);
} catch (IOException e) {
System.err.println("Error reading file: " + args[i]);
e.printStackTrace();
}
}
System.out.println("Word count:" + Arrays.toString(wordCount));
int total = 0;
for (int count : wordCount) {
total += count;
}
System.out.println("Total word count:" + total);
System.out.println("Total time "+(System.currentTimeMillis()-startTime) + " ms");
}
}
Эта версия запускает один поток для каждого файла.

Код: Выделить всё

public class WordCountMT {

public static int countWords(String filename) throws IOException {
// same code
}

private static class CounterWorker implements Runnable {
private String filename;
private int index;
private int[] wordCount;

public CounterWorker(String filename, int index, int[] wordCount) {
this.filename = filename;
this.index = index;
this.wordCount = wordCount;
}

@Override
public void run() {
try {
wordCount[index] = countWords(filename);
} catch (IOException e) {
System.err.println("Error reading file: " + filename);
e.printStackTrace();
}
}
}

public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int[] wordCount = new int[args.length];
List th = new ArrayList();

for (int i = 0; i < args.length; i++) {
th.add(new Thread(new CounterWorker(args[i], i, wordCount)));
th.get(i).start();
}
try {
for (Thread t : th) {
t.join();

}
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("Word count:" + Arrays.toString(wordCount));
int total = 0;
for (int count : wordCount) {
total += count;
}
System.out.println("Total word count:" + total);

System.out.println("Total time "+(System.currentTimeMillis()-startTime) + " ms");
}
}
Хорошо, это очень простой пример, используемый для обучения. Теперь я понял, что создание большого количества потоков иногда приводит к обратным результатам, но эти следы странные:
Не MT

Код: Выделить всё

    Time for file /tmp/data/data6-5.txt : 14 ms for 1468 words
Time for file /tmp/data/data5-6.txt : 3 ms for 1468 words
Time for file /tmp/data/data5.txt : 1 ms for 390 words
Time for file /tmp/data/data5-5.txt : 1 ms for 780 words
Time for file /tmp/data/data7.txt : 1 ms for 1078 words
Time for file /tmp/data/data6.txt : 2 ms for 1078 words
Time for file /tmp/data/data6-6.txt : 2 ms for 2156 words
Time for file /tmp/data/data8.txt : 1 ms for 1078 words
Time for file /tmp/data/data3.txt : 0 ms for 390 words
Time for file /tmp/data/data6-7.txt : 1 ms for 2156 words
Time for file /tmp/data/data4.txt : 1 ms for 390 words
Time for file /tmp/data/data5-4.txt : 1 ms for 780 words
Time for file /tmp/data/data1.txt : 0 ms for 390 words
Time for file /tmp/data/data2.txt : 0 ms for 390 words
Time for file /tmp/data/data9.txt : 1 ms for 1078 words
Time for file /tmp/data/data5-7.txt : 0 ms for 1468 words
Time for file /tmp/data/data6-4.txt : 1 ms for 1468 words
Word count:[1468, 1468, 390, 780, 1078, 1078, 2156, 1078, 390, 2156, 390, 780, 390, 390, 1078, 1468, 1468]
Total word count:18006
Total time 54 ms
С помощью MT

Код: Выделить всё

    Time for file /tmp/data/data3.txt : 46 ms for 390 words
Time for file /tmp/data/data5-4.txt : 54 ms for 780 words
Time for file /tmp/data/data5-5.txt : 58 ms for 780 words
Time for file /tmp/data/data1.txt : 45 ms for 390 words
Time for file /tmp/data/data6-5.txt : 70 ms for 1468 words
Time for file /tmp/data/data5-7.txt : 68 ms for 1468 words
Time for file /tmp/data/data5.txt : 45 ms for 390 words
Time for file /tmp/data/data7.txt : 65 ms for 1078 words
Time for file /tmp/data/data2.txt : 43 ms for 390 words
Time for file /tmp/data/data6.txt : 64 ms for 1078 words
Time for file /tmp/data/data5-6.txt : 70 ms for 1468 words
Time for file /tmp/data/data9.txt : 58 ms for 1078 words
Time for file /tmp/data/data6-7.txt : 71 ms for 2156 words
Time for file /tmp/data/data8.txt : 66 ms for 1078 words
Time for file /tmp/data/data6-6.txt : 72 ms for 2156 words
Time for file /tmp/data/data4.txt : 46 ms for 390 words
Time for file /tmp/data/data6-4.txt : 68 ms for 1468 words
Word count:[1468, 1468, 390, 780, 1078, 1078, 2156, 1078, 390, 2156, 390, 780, 390, 390, 1078, 1468, 1468]
Total word count:18006
Total time 98 ms
Таким образом, общее время стало хуже, но также время на файл полностью увеличилось, например. data8 занимал 1 мс, теперь занимает 66 мс!
Как мне лучше понять, почему? Могу ли я измерить потребление времени ЦП вместо времени ожидания?
Это потому, что параллельные запросы ввода-вывода на самом деле медленнее?
Спасибо за объяснение или любые дополнительные тесты/инструменты, которые я мог бы добавить чтобы лучше определить проблему.

Подробнее здесь: https://stackoverflow.com/questions/790 ... sequential
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»